knartform 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +40 -0
- data/bin/audit_manifest +58 -0
- data/bin/batch_validation +128 -0
- data/bin/composite_graphs +47 -0
- data/bin/composite_to_dot +34 -0
- data/bin/knartform +26 -0
- data/bin/manifest_to_cds_connect +175 -0
- data/bin/spot_check +134 -0
- data/bin/update_manifest +147 -0
- data/knartform.gemspec +23 -0
- data/lib/common.rb +264 -0
- data/lib/knartform.rb +5 -0
- data/lib/knartform/action_group.rb +17 -0
- data/lib/knartform/knart.rb +71 -0
- data/lib/metadata.slim +12 -0
- data/lib/spot_check.slim +324 -0
- data/lib/views/action_group.slim +90 -0
- data/lib/views/documentation_template.slim +152 -0
- data/lib/views/dummy_add_button.slim +4 -0
- data/lib/views/dummy_drag_control.slim +3 -0
- data/lib/views/dummy_edit_and_delete.slim +5 -0
- data/lib/views/dummy_edit_button.slim +4 -0
- data/lib/views/unsupported.slim +4 -0
- metadata +159 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 05dcabe6d14a5de527125fd163e244d7bea657003110b822060466d88a91d638
|
4
|
+
data.tar.gz: 436cd22c232b0fdb207de4c41b87abe50577fb61ccbbdf6b40e8f14fd88d4841
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3b5e27b612d7299080f9e159ea379f3526689f05c99d9e4465513249da7dfbe73b9fbefd6ca4980f3554c83948e246ca38ec783909649693fab95eeebd799a64
|
7
|
+
data.tar.gz: af103048da19a284c91e1a47637e48ac27f4e0ac4024d4223b0836f5588bb592bef034e83397bd82adf525478370f78786ae5ccf845da5e47c93692f25ce07ae
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.DS_Store
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
knartform (0.6.0)
|
5
|
+
httparty
|
6
|
+
nokogiri
|
7
|
+
slim
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
httparty (0.16.4)
|
13
|
+
mime-types (~> 3.0)
|
14
|
+
multi_xml (>= 0.5.2)
|
15
|
+
mime-types (3.2.2)
|
16
|
+
mime-types-data (~> 3.2015)
|
17
|
+
mime-types-data (3.2018.0812)
|
18
|
+
mini_portile2 (2.4.0)
|
19
|
+
minitest (5.11.3)
|
20
|
+
multi_xml (0.6.0)
|
21
|
+
nokogiri (1.10.1)
|
22
|
+
mini_portile2 (~> 2.4.0)
|
23
|
+
rake (12.3.2)
|
24
|
+
slim (4.0.1)
|
25
|
+
temple (>= 0.7.6, < 0.9)
|
26
|
+
tilt (>= 2.0.6, < 2.1)
|
27
|
+
temple (0.8.0)
|
28
|
+
tilt (2.0.9)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
bundler
|
35
|
+
knartform!
|
36
|
+
minitest
|
37
|
+
rake
|
38
|
+
|
39
|
+
BUNDLED WITH
|
40
|
+
1.17.2
|
data/bin/audit_manifest
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'pp'
|
5
|
+
require 'byebug'
|
6
|
+
require 'httparty'
|
7
|
+
|
8
|
+
require_relative "../lib/common"
|
9
|
+
include Repository
|
10
|
+
HELP = <<EOF
|
11
|
+
|
12
|
+
Audits an existing repository manifest.json by checking for the existance of referenced file paths and URLs. As all paths are relative to the provided manifest.json file, manually specifying the content directory is unnecessary.
|
13
|
+
|
14
|
+
USAGE: #{__FILE__} <manifest.json>
|
15
|
+
|
16
|
+
EXAMPLE:
|
17
|
+
#{__FILE__} manifest.json
|
18
|
+
|
19
|
+
EOF
|
20
|
+
|
21
|
+
|
22
|
+
def report(good, bad)
|
23
|
+
puts "\nGood file references: #{good.length}"
|
24
|
+
puts "Bad file references: #{bad.length}"
|
25
|
+
bad.each do |n| puts "\t#{[n['path'],n['url']].join(' ')}" end
|
26
|
+
puts "\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
if(ARGV.length != 1)
|
30
|
+
puts HELP
|
31
|
+
exit 1
|
32
|
+
else
|
33
|
+
file = ARGV[0]
|
34
|
+
manifest = JSON.parse(File.read(file))
|
35
|
+
root = File.dirname(File.expand_path(file))
|
36
|
+
good, bad = audit_content_directory(root, manifest)
|
37
|
+
report(good, bad)
|
38
|
+
|
39
|
+
valid = []
|
40
|
+
invalid = []
|
41
|
+
manifest['groups'].each do |group|
|
42
|
+
group['items'].each do |item|
|
43
|
+
path = "#{root}/#{item['path']}"
|
44
|
+
# puts "#{path}"
|
45
|
+
if item['validation']
|
46
|
+
if item['validation']['passed']
|
47
|
+
valid << item
|
48
|
+
else
|
49
|
+
invalid << item
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
puts "Declared as valid: #{valid.count}"
|
55
|
+
puts "Declared as invalid: #{invalid.count}"
|
56
|
+
|
57
|
+
exit 0
|
58
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'pp'
|
5
|
+
require 'open3'
|
6
|
+
require 'byebug'
|
7
|
+
|
8
|
+
require_relative '../lib/common'
|
9
|
+
include Repository
|
10
|
+
|
11
|
+
HELP = <<EOF.freeze
|
12
|
+
|
13
|
+
Performs validation against all artifacts. Provide the manifest file as the only argument. XML schema validation on composites is non-recursive. This may take a few minutes. Be patient! If the existing and new manifest files are the same, the existing file will be *overwriten* in place. Be sure you have a backup handy if you're doing this!
|
14
|
+
|
15
|
+
The --update or --no-update is required, indicating whether existing passed validations should be re-run or not, respectively.
|
16
|
+
|
17
|
+
USAGE: #{__FILE__} <manifest.json> --(no-)update <new_manifest.json>
|
18
|
+
|
19
|
+
EXAMPLE:
|
20
|
+
#{__FILE__} manifest.json manifest-new.json
|
21
|
+
|
22
|
+
EOF
|
23
|
+
|
24
|
+
# SCRIPT_DIR = File.dirname(File.expand_path(__FILE__))
|
25
|
+
ARTIFACT_SCHEMA = 'doc/schema/1.3-revised/knowledgeartifact/knowledgedocument.xsd'.freeze
|
26
|
+
COMPOSITE_SCHEMA = 'doc/schema/composite-draft/knowledgeartifact/compositeknowledgedocument.xsd'.freeze
|
27
|
+
|
28
|
+
UPDATE_EXISTING_VALIDATIONS = false
|
29
|
+
|
30
|
+
def should_validate(old)
|
31
|
+
UPDATE_EXISTING_VALIDATIONS || old.nil? || !old.dig('passed')
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate_composites(root, manifest)
|
35
|
+
manifest['groups'].each do |group|
|
36
|
+
group['items'].each do |item|
|
37
|
+
path = "#{root}/#{item['path']}"
|
38
|
+
# puts "#{path}"
|
39
|
+
old = item['validation']
|
40
|
+
if (COMPOSITE_MIME_TYPES.include? item['mimeType']) && should_validate(old)
|
41
|
+
item['validation'] = validate(root + '/' + item['path'], root + '/' + COMPOSITE_SCHEMA)
|
42
|
+
pp item
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def validate_individuals(root, manifest)
|
49
|
+
# list = Dir.glob("#{root}/**/*KRprt*.xml", File::FNM_CASEFOLD)
|
50
|
+
individuals = []
|
51
|
+
manifest['groups'].each do |group|
|
52
|
+
group['items'].each do |item|
|
53
|
+
path = "#{root}/#{item['path']}"
|
54
|
+
# puts "#{path}"
|
55
|
+
old = item['validation']
|
56
|
+
if (KNART_MIME_TYPES.include? item['mimeType']) && should_validate(old)
|
57
|
+
individuals << item
|
58
|
+
item['validation'] = validate(root + '/' + item['path'], root + '/' + ARTIFACT_SCHEMA)
|
59
|
+
pp item
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def validate(_file, _schema)
|
66
|
+
cmd = "xmllint --noout --schema #{_schema} #{_file}"
|
67
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
68
|
+
validation = {
|
69
|
+
passed: status.exitstatus == 0,
|
70
|
+
code: status.exitstatus,
|
71
|
+
display: xmllint_status_code(status.exitstatus),
|
72
|
+
errors: nil,
|
73
|
+
run_at: Time.now
|
74
|
+
}
|
75
|
+
validation[:errors] = stderr unless validation[:passed]
|
76
|
+
validation
|
77
|
+
end
|
78
|
+
|
79
|
+
def xmllint_status_code(code)
|
80
|
+
case code
|
81
|
+
when 0
|
82
|
+
'valid!'
|
83
|
+
when 1
|
84
|
+
'Unclassified'
|
85
|
+
when 2
|
86
|
+
'Error in DTD'
|
87
|
+
when 3
|
88
|
+
'Validation error'
|
89
|
+
when 4
|
90
|
+
'Validation error'
|
91
|
+
when 5
|
92
|
+
'Error in schema compilation'
|
93
|
+
when 6
|
94
|
+
'Error writing output'
|
95
|
+
when 7
|
96
|
+
'Error in pattern (generated when --pattern option is used)'
|
97
|
+
when 8
|
98
|
+
'Error in Reader registration (generated when --chkregister option is used)'
|
99
|
+
when 9
|
100
|
+
'Out of memory error'
|
101
|
+
else
|
102
|
+
'Unknown :-/'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
if ARGV.length != 3
|
107
|
+
puts HELP
|
108
|
+
exit 1
|
109
|
+
else
|
110
|
+
file = ARGV[0]
|
111
|
+
manifest = JSON.parse(File.read(file))
|
112
|
+
root = File.dirname(File.expand_path(file))
|
113
|
+
|
114
|
+
if ARGV[1] == '--update'
|
115
|
+
UPDATE_EXISTING_VALIDATIONS = true
|
116
|
+
end
|
117
|
+
|
118
|
+
# Open the output first so we don't waste time if it's not writable.
|
119
|
+
out = File.open(ARGV[2], 'w')
|
120
|
+
|
121
|
+
validate_composites(root, manifest)
|
122
|
+
validate_individuals(root, manifest)
|
123
|
+
|
124
|
+
out.write(JSON.pretty_generate(manifest))
|
125
|
+
out.close
|
126
|
+
|
127
|
+
exit 0
|
128
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'pp'
|
5
|
+
require 'byebug'
|
6
|
+
require 'nokogiri'
|
7
|
+
# require 'slim'
|
8
|
+
require 'erb'
|
9
|
+
require 'digest/sha1'
|
10
|
+
require 'open3'
|
11
|
+
|
12
|
+
require_relative "../lib/common"
|
13
|
+
include Repository
|
14
|
+
|
15
|
+
HELP = <<EOF
|
16
|
+
|
17
|
+
Generates SVG diagrams for all composite KNARTS in the provided in the directory.
|
18
|
+
|
19
|
+
USAGE: #{__FILE__} <directory>
|
20
|
+
|
21
|
+
EXAMPLE:
|
22
|
+
#{__FILE__} content
|
23
|
+
|
24
|
+
EOF
|
25
|
+
|
26
|
+
|
27
|
+
if(ARGV.length != 1)
|
28
|
+
puts HELP
|
29
|
+
exit 1
|
30
|
+
else
|
31
|
+
# path = File.expand_path(ARGV[0])
|
32
|
+
items = content_directory_to_item_tree(ARGV[0])
|
33
|
+
items.each do |i|
|
34
|
+
# puts "#{i['path']} #{i['mimeType']}"
|
35
|
+
# puts i['mimeType']
|
36
|
+
# byebug
|
37
|
+
if COMPOSITE_MIME_TYPES.include?(i['mimeType'].to_s)
|
38
|
+
path = i['path'].to_s
|
39
|
+
doc = Nokogiri::XML(File.open(path))
|
40
|
+
dot = generate_dot(doc)
|
41
|
+
svg = "#{path}.svg"
|
42
|
+
stdout_str, error_str, status = Open3.capture3('dot', '-Tsvg', '-o', svg, stdin_data: dot)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
exit 0
|
47
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'pp'
|
5
|
+
require 'byebug'
|
6
|
+
require 'nokogiri'
|
7
|
+
# require 'slim'
|
8
|
+
require 'erb'
|
9
|
+
require 'digest/sha1'
|
10
|
+
|
11
|
+
require_relative "../lib/common"
|
12
|
+
include Repository
|
13
|
+
|
14
|
+
HELP = <<EOF
|
15
|
+
|
16
|
+
Transform the event/trigger structure of a composite knowledge artifact into a visual representation using DOT syntax. Rendering may be done using `graphviz` or any number of existing tools.
|
17
|
+
|
18
|
+
USAGE: #{__FILE__} <composite.xml>
|
19
|
+
|
20
|
+
EXAMPLE:
|
21
|
+
#{__FILE__} my_composite_knart.xml |dot -Tsvg -o graph.svg
|
22
|
+
|
23
|
+
EOF
|
24
|
+
|
25
|
+
|
26
|
+
if(ARGV.length != 1)
|
27
|
+
puts HELP
|
28
|
+
exit 1
|
29
|
+
else
|
30
|
+
path = File.expand_path(ARGV[0])
|
31
|
+
doc = Nokogiri::XML(File.open(path))
|
32
|
+
puts generate_dot(doc)
|
33
|
+
exit 0
|
34
|
+
end
|
data/bin/knartform
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Example KNART compilation.
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'httparty'
|
7
|
+
require 'nokogiri'
|
8
|
+
|
9
|
+
require_relative '../lib/knartform'
|
10
|
+
|
11
|
+
if ARGV.length != 2
|
12
|
+
puts "\n\tUsage: #{__FILE__} <input-knowledge-document.xml> <output.html>\n\n"
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
path = ARGV[0]
|
16
|
+
if File.exists? ARGV[0]
|
17
|
+
knart = Knartform::Knart.new File.new(ARGV[0])
|
18
|
+
out = File.open(ARGV[1], 'w')
|
19
|
+
out.write knart.to_html
|
20
|
+
out.close
|
21
|
+
else
|
22
|
+
puts "File doesn't exist."
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "Done."
|
26
|
+
exit 0
|
@@ -0,0 +1,175 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'pp'
|
5
|
+
require 'byebug'
|
6
|
+
require 'nokogiri'
|
7
|
+
require 'slim'
|
8
|
+
|
9
|
+
require_relative "../lib/common"
|
10
|
+
include Repository
|
11
|
+
|
12
|
+
HELP = <<EOF
|
13
|
+
|
14
|
+
Converts an existing manifest.json file to the expanded structure required for import into CDS Connect.
|
15
|
+
|
16
|
+
USAGE: #{__FILE__} <manifest.json> <connect.json>
|
17
|
+
|
18
|
+
EXAMPLE:
|
19
|
+
#{__FILE__} manifest.json connect.json
|
20
|
+
|
21
|
+
EOF
|
22
|
+
|
23
|
+
def extract_metadata(doc)
|
24
|
+
metadata = {
|
25
|
+
name: doc.xpath("///xmlns:metadata/xmlns:title/@value").first.to_s,
|
26
|
+
description: doc.xpath("///xmlns:metadata/xmlns:description/@value").first.to_s,
|
27
|
+
artifactType: doc.xpath("//xmlns:artifactType/@value").first.to_s,
|
28
|
+
identifier: doc.xpath("///xmlns:metadata/xmlns:identifiers/xmlns:identifier/@extension").select{|n| n.to_s.length == 36}.first.to_s,
|
29
|
+
status: doc.xpath("///xmlns:metadata/xmlns:status/@value").first.to_s,
|
30
|
+
experimental: true,
|
31
|
+
license: 'Apache 2.0',
|
32
|
+
copyright: 'Copyright © 2018 Veterans Health Administration, Department of Veterans Affairs. All rights reserved. Contributions from external parties are property of respective copyright holders.',
|
33
|
+
steward: 'Veterans Health Administration',
|
34
|
+
publisher: 'Veterans Health Administration',
|
35
|
+
ip_attestation: true,
|
36
|
+
knowledge_level: 3,
|
37
|
+
pilot_experience: 'None',
|
38
|
+
date_reviewed: doc.xpath("//xmlns:eventHistory/xmlns:artifactLifeCycleEvent[xmlns:eventType/@value = 'Reviewed']/xmlns:eventDateTime/@value").first.to_s,
|
39
|
+
date_published: doc.xpath("//xmlns:eventHistory/xmlns:artifactLifeCycleEvent[xmlns:eventType/@value = 'Published']/xmlns:eventDateTime/@value").first.to_s,
|
40
|
+
date_created: doc.xpath("//xmlns:eventHistory/xmlns:artifactLifeCycleEvent[xmlns:eventType/@value = 'Created']/xmlns:eventDateTime/@value").first.to_s,
|
41
|
+
date_approved: nil,
|
42
|
+
date_expired: nil
|
43
|
+
}
|
44
|
+
metadata[:date_reviewed] = nil if metadata[:date_reviewed].empty?
|
45
|
+
metadata[:date_published] = nil if metadata[:date_published].empty?
|
46
|
+
metadata[:date_created] = nil if metadata[:date_created].empty?
|
47
|
+
# byebug
|
48
|
+
metadata[:contributions] = ''
|
49
|
+
doc.xpath("//xmlns:contributions//xmlns:contributor").each do |c|
|
50
|
+
first = c.xpath('./xmlns:name/dt:part[@type = "GIV"]/@value').first.to_s
|
51
|
+
last = c.xpath('./xmlns:name/dt:part[@type = "FAM"]/@value').first.to_s
|
52
|
+
title = c.xpath('./xmlns:name/dt:part[@type = "TITLE"]/@value').first.to_s
|
53
|
+
affiliation = c.xpath('./xmlns:affiliation/xmlns:name/@value').first.to_s
|
54
|
+
metadata[:contributions] += "<div>" +
|
55
|
+
"<b><span>#{first}</span> <span>#{last}</span></b>" +
|
56
|
+
", <span>#{title}</span>, <i><span>#{affiliation}</span></i>" +
|
57
|
+
"</div>"
|
58
|
+
end
|
59
|
+
|
60
|
+
metadata[:references] = '<dl>'
|
61
|
+
doc.xpath("//xmlns:relatedResources/xmlns:relatedResource").each do |r|
|
62
|
+
rel = r.xpath('./xmlns:relationship/@value').first.to_s.split(/(?=[A-Z])/).join(' ')
|
63
|
+
title = r.xpath('./xmlns:resources/xmlns:resource/xmlns:title/@value').first.to_s
|
64
|
+
description = r.xpath('./xmlns:resources/xmlns:resource/xmlns:description/@value').first.to_s
|
65
|
+
metadata[:references] += "<dt>#{rel}</dt><dd>#{title}</dd>"
|
66
|
+
# #{description}
|
67
|
+
end
|
68
|
+
metadata[:references] += '</dl>'
|
69
|
+
|
70
|
+
metadata[:cautions] = '<p>THE CLINICAL CONTENT IN THIS DOCUMENT IS NOT DIRECTLY SUITABLE FOR CLINICAL USE AS PRESENTED SINCE IT HAS NOT BEEN TESTED IN A CLINICAL ENVIRONMENT. IT HAS NEVER BEEN PILOTED, NEVER 100% REPRESENTS THE INTENT OF THE CLINICAL SUBJECT MATTER EXPERTS, AND MAY CAUSE HARM IF APPLIED AS-IS. THIS WORK IS MADE AVAILABLE WITHOUT ANY WARRANTY WHATSOEVER, AND WITHOUT CLAIMS, EXPRESSED OR IMPLIED, OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p>'
|
71
|
+
metadata[:usage] = '<dl>'
|
72
|
+
doc.xpath("//xmlns:applicability/xmlns:coverage").each do |c|
|
73
|
+
focus = c.xpath('./xmlns:focus/@value').first.to_s.split(/(?=[A-Z])/).join(' ')
|
74
|
+
description = c.xpath('./xmlns:description/@value').first.to_s
|
75
|
+
code = c.xpath('./xmlns:value/@code').first.to_s
|
76
|
+
# metadata[:usage] += "#{focus}: #{description}"
|
77
|
+
# metadata[:usage] += " (#{code})" if code.length > 0
|
78
|
+
# metadata[:usage] += "\n"
|
79
|
+
metadata[:usage] += "<dt>#{focus}</dt>" +
|
80
|
+
# "<dd>#{description} #{code.length > 0 ? ('(' + code + ')') : ''}</dd>"
|
81
|
+
"<dd>#{description}</dd>"
|
82
|
+
end
|
83
|
+
metadata[:usage] += '</dl>'
|
84
|
+
|
85
|
+
metadata[:decision_notes] = "<p>See attached resource files for additional details. Department of Veterans Affairs, Veterans Health Administration, Office of Informatics and Information Governance, Clinical Decision Support (CDS) Content and Health Level 7 (HL7)-Compliant Knowledge Artifacts (KNARTs) Eye Care Clinical Content White Paper, VA118-16-D-1008, Task Order VA-118-16-F-1008-0007, June, 2018.</p>"
|
86
|
+
metadata[:decision_notes] += '<dl>'
|
87
|
+
doc.xpath("//xmlns:supportingEvidence//xmlns:resource").each do |c|
|
88
|
+
title = c.xpath('./xmlns:title/@value').first.to_s
|
89
|
+
location = c.xpath('./xmlns:location/@value').first.to_s
|
90
|
+
citation = c.xpath('./xmlns:citation/@value').first.to_s
|
91
|
+
metadata[:decision_notes] += "<dt>#{citation}</dt><dd><a href=\"#{location}\">#{location}</a></dd>"
|
92
|
+
# #{citation}
|
93
|
+
end
|
94
|
+
metadata[:decision_notes] += '</dl>'
|
95
|
+
|
96
|
+
# metadata[:bindings] = []
|
97
|
+
metadata
|
98
|
+
end
|
99
|
+
|
100
|
+
def extract_knart_metadata(doc)
|
101
|
+
# We'll cover the basics first.
|
102
|
+
metadata = extract_metadata(doc)
|
103
|
+
# Global ELM stuff.
|
104
|
+
exps = doc.xpath("/xmlns:knowledgeDocument/xmlns:expressions/xmlns:def")
|
105
|
+
|
106
|
+
metadata[:expressions] = exps.collect{|e| {
|
107
|
+
name: e.xpath("@name").to_s,
|
108
|
+
type: e.xpath('elm:expression/@xsi:type').to_s
|
109
|
+
}}
|
110
|
+
# puts metadata
|
111
|
+
metadata
|
112
|
+
end
|
113
|
+
|
114
|
+
def extract_composite_metadata(doc)
|
115
|
+
metadata = extract_metadata(doc)
|
116
|
+
# metadata[:artifacts] =
|
117
|
+
xml = doc.xpath('//xmlns:containedArtifacts').to_s
|
118
|
+
# byebug
|
119
|
+
# puts xml
|
120
|
+
metadata[:artifacts] = Hash.from_xml(xml)[:containedArtifacts][:artifact]
|
121
|
+
# puts metadata
|
122
|
+
metadata
|
123
|
+
end
|
124
|
+
|
125
|
+
def group_by_tag(root, manifest)
|
126
|
+
connect = {}
|
127
|
+
manifest['groups'].each do |group|
|
128
|
+
group['items'].each do |item|
|
129
|
+
item['tags'].each do |tag|
|
130
|
+
if !connect[tag]
|
131
|
+
connect[tag] = {
|
132
|
+
technical_files: [],
|
133
|
+
miscellaneous_files: []
|
134
|
+
}
|
135
|
+
end
|
136
|
+
# puts connect.to_json
|
137
|
+
# puts connect[tag][:items]
|
138
|
+
#
|
139
|
+
if KNART_MIME_TYPES.include? item['mimeType']
|
140
|
+
doc = Nokogiri::XML(File.open(item['path']))
|
141
|
+
connect[tag].merge! extract_knart_metadata(doc)
|
142
|
+
connect[tag][:technical_files] << item
|
143
|
+
elsif COMPOSITE_MIME_TYPES.include? item['mimeType']
|
144
|
+
doc = Nokogiri::XML(File.open(item['path']))
|
145
|
+
connect[tag].merge! extract_composite_metadata(doc)
|
146
|
+
connect[tag][:technical_files] << item
|
147
|
+
else
|
148
|
+
connect[tag][:miscellaneous_files] << item
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
connect
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
|
158
|
+
def write_results(out, connect)
|
159
|
+
file = File.open(out, 'w')
|
160
|
+
file.write JSON.pretty_generate(connect)
|
161
|
+
file.close
|
162
|
+
end
|
163
|
+
|
164
|
+
if(ARGV.length != 2)
|
165
|
+
puts HELP
|
166
|
+
exit 1
|
167
|
+
else
|
168
|
+
file = ARGV[0]
|
169
|
+
manifest = JSON.parse(File.read(file))
|
170
|
+
root = File.dirname(File.expand_path(file))
|
171
|
+
connect = group_by_tag(root, manifest)
|
172
|
+
write_results ARGV[1], connect
|
173
|
+
# pp connect
|
174
|
+
exit 0
|
175
|
+
end
|