oddb2xml 1.0.10 → 1.1.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.
- data/History.txt +4 -0
- data/README.md +1 -1
- data/lib/oddb2xml/builder.rb +63 -7
- data/lib/oddb2xml/cli.rb +33 -23
- data/lib/oddb2xml/compressor.rb +2 -3
- data/lib/oddb2xml/extractor.rb +19 -4
- data/lib/oddb2xml/version.rb +1 -1
- data/spec/compressor_spec.rb +2 -0
- data/spec/downloader_spec.rb +31 -0
- data/spec/spec_helper.rb +36 -2
- metadata +38 -62
data/History.txt
CHANGED
data/README.md
CHANGED
data/lib/oddb2xml/builder.rb
CHANGED
@@ -38,15 +38,32 @@ module Oddb2xml
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
private
|
41
|
-
def
|
42
|
-
@substances
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
def prepare_substances
|
42
|
+
unless @substances
|
43
|
+
@substances = []
|
44
|
+
@items.values.uniq.each do |seq|
|
45
|
+
seq[:substances].each do |sub|
|
46
|
+
@substances << sub[:name]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
@substances.uniq!
|
50
|
+
@substances.sort!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
def prepare_limitations
|
54
|
+
unless @limitations
|
55
|
+
@limitations = []
|
56
|
+
@items.values.uniq.each do |seq|
|
57
|
+
seq[:packages].each_value do |pac|
|
58
|
+
@limitations += pac[:limitations]
|
59
|
+
end
|
46
60
|
end
|
61
|
+
@limitations.uniq!
|
62
|
+
@limitations.sort_by!{|lim| lim[:code] }
|
47
63
|
end
|
48
|
-
|
49
|
-
|
64
|
+
end
|
65
|
+
def build_substance
|
66
|
+
prepare_substances
|
50
67
|
_builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
|
51
68
|
xml.doc.tag_suffix = @tag_suffix
|
52
69
|
datetime = Time.new.strftime('%FT%T.%7N%z')
|
@@ -77,7 +94,45 @@ module Oddb2xml
|
|
77
94
|
end
|
78
95
|
_builder.to_xml
|
79
96
|
end
|
97
|
+
def build_limitation
|
98
|
+
prepare_limitations
|
99
|
+
_builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
|
100
|
+
xml.doc.tag_suffix = @tag_suffix
|
101
|
+
datetime = Time.new.strftime('%FT%T.%7N%z')
|
102
|
+
xml.LIMITATION(
|
103
|
+
'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
104
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
105
|
+
'xmlns' => 'http://wiki.oddb.org/wiki.php?pagename=Swissmedic.Datendeklaration',
|
106
|
+
'CREATION_DATETIME' => datetime,
|
107
|
+
'PROD_DATE' => datetime,
|
108
|
+
'VALID_DATE' => datetime,
|
109
|
+
) {
|
110
|
+
@limitations.each do |lim|
|
111
|
+
xml.LIM('DT' => '') {
|
112
|
+
xml.LIMCD lim[:code]
|
113
|
+
xml.IT lim[:it]
|
114
|
+
xml.LIMTYP lim[:type]
|
115
|
+
xml.LIMVAL lim[:value]
|
116
|
+
xml.DSCRD lim[:desc_de]
|
117
|
+
xml.DSCRF lim[:desc_fr]
|
118
|
+
xml.VDAT lim[:vdate]
|
119
|
+
if lim[:del]
|
120
|
+
xml.DEL 3
|
121
|
+
end
|
122
|
+
}
|
123
|
+
end
|
124
|
+
xml.RESULT {
|
125
|
+
xml.OK_ERROR 'OK'
|
126
|
+
xml.NBR_RECORD @limitations.length.to_s
|
127
|
+
xml.ERROR_CODE ''
|
128
|
+
xml.MESSAGE ''
|
129
|
+
}
|
130
|
+
}
|
131
|
+
end
|
132
|
+
_builder.to_xml
|
133
|
+
end
|
80
134
|
def build_product
|
135
|
+
prepare_substances
|
81
136
|
# merge company info from swissINDEX
|
82
137
|
objects = []
|
83
138
|
objects = @items.values.uniq.map do |seq|
|
@@ -218,6 +273,7 @@ module Oddb2xml
|
|
218
273
|
_builder.to_xml
|
219
274
|
end
|
220
275
|
def build_article
|
276
|
+
prepare_limitations
|
221
277
|
objects = [] # base is 'DE'
|
222
278
|
@index['DE'].each_pair do |pharmacode, index|
|
223
279
|
object = {
|
data/lib/oddb2xml/cli.rb
CHANGED
@@ -9,6 +9,7 @@ require 'oddb2xml/compressor'
|
|
9
9
|
module Oddb2xml
|
10
10
|
class Cli
|
11
11
|
SUBJECTS = %w[product article]
|
12
|
+
ADDITIONS = %w[substance limitation]
|
12
13
|
LANGUAGES = %w[DE FR] # EN does not exist
|
13
14
|
def initialize(args)
|
14
15
|
@options = args
|
@@ -35,7 +36,10 @@ module Oddb2xml
|
|
35
36
|
threads << Thread.new do
|
36
37
|
downloader = BagXmlDownloader.new
|
37
38
|
xml = downloader.download
|
38
|
-
@
|
39
|
+
@mutex.synchronize do
|
40
|
+
hsh = BagXmlExtractor.new(xml).to_hash
|
41
|
+
@items = hsh
|
42
|
+
end
|
39
43
|
end
|
40
44
|
LANGUAGES.each do |lang|
|
41
45
|
# swissindex
|
@@ -52,13 +56,11 @@ module Oddb2xml
|
|
52
56
|
end
|
53
57
|
threads.map(&:join)
|
54
58
|
build
|
59
|
+
compress if @options[:compress_ext]
|
55
60
|
report
|
56
61
|
end
|
57
62
|
private
|
58
63
|
def build
|
59
|
-
files = {}
|
60
|
-
prefix = (@options[:tag_suffix] || 'oddb').gsub(/^_|_$/, '').downcase
|
61
|
-
SUBJECTS.each{ |sbj| files[sbj] = "#{prefix}_#{sbj}.xml" }
|
62
64
|
begin
|
63
65
|
files.each_pair do |sbj, file|
|
64
66
|
builder = Builder.new do |builder|
|
@@ -76,23 +78,9 @@ module Oddb2xml
|
|
76
78
|
builder.fridges = @fridges
|
77
79
|
builder.tag_suffix = @options[:tag_suffix]
|
78
80
|
end
|
79
|
-
if file =~ /(product)/
|
80
|
-
xml = builder.to_xml('substance')
|
81
|
-
File.open(file.gsub($1, 'substance'), 'w:utf-8'){ |fh| fh << xml }
|
82
|
-
end
|
83
81
|
xml = builder.to_xml
|
84
82
|
File.open(file, 'w:utf-8'){ |fh| fh << xml }
|
85
83
|
end
|
86
|
-
if @options[:compress_ext]
|
87
|
-
compressor = Compressor.new(prefix, @options[:compress_ext])
|
88
|
-
files.values.each do |file|
|
89
|
-
if file =~ /(product)/
|
90
|
-
compressor.contents << file.gsub($1, 'substance')
|
91
|
-
end
|
92
|
-
compressor.contents << file
|
93
|
-
end
|
94
|
-
compressor.finalize!
|
95
|
-
end
|
96
84
|
rescue Interrupt
|
97
85
|
files.values.each do |file|
|
98
86
|
if File.exist? file
|
@@ -102,6 +90,27 @@ module Oddb2xml
|
|
102
90
|
raise Interrupt
|
103
91
|
end
|
104
92
|
end
|
93
|
+
def compress
|
94
|
+
compressor = Compressor.new(prefix, @options[:compress_ext])
|
95
|
+
files.values.each do |file|
|
96
|
+
if File.exists?(file)
|
97
|
+
compressor.contents << file
|
98
|
+
end
|
99
|
+
end
|
100
|
+
compressor.finalize!
|
101
|
+
end
|
102
|
+
def files
|
103
|
+
unless @_files
|
104
|
+
@_files = {}
|
105
|
+
(ADDITIONS + SUBJECTS).each do|sbj|
|
106
|
+
@_files[sbj] = "#{prefix}_#{sbj.to_s}.xml"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
@_files
|
110
|
+
end
|
111
|
+
def prefix
|
112
|
+
@_prefix ||= (@options[:tag_suffix] || 'oddb').gsub(/^_|_$/, '').downcase
|
113
|
+
end
|
105
114
|
def report
|
106
115
|
lines = []
|
107
116
|
LANGUAGES.each do |lang|
|
@@ -114,11 +123,12 @@ module Oddb2xml
|
|
114
123
|
puts lines.join("\n")
|
115
124
|
end
|
116
125
|
def types # swissindex
|
117
|
-
|
118
|
-
[:
|
119
|
-
|
120
|
-
|
121
|
-
|
126
|
+
@_types ||=
|
127
|
+
if @options[:nonpharma]
|
128
|
+
[:pharma, :nonpharma]
|
129
|
+
else
|
130
|
+
[:pharma]
|
131
|
+
end
|
122
132
|
end
|
123
133
|
end
|
124
134
|
end
|
data/lib/oddb2xml/compressor.rb
CHANGED
@@ -14,7 +14,7 @@ module Oddb2xml
|
|
14
14
|
super()
|
15
15
|
end
|
16
16
|
def finalize!
|
17
|
-
|
17
|
+
if @contents.empty?
|
18
18
|
return false
|
19
19
|
end
|
20
20
|
begin
|
@@ -35,8 +35,7 @@ module Oddb2xml
|
|
35
35
|
File.unlink file
|
36
36
|
end
|
37
37
|
end
|
38
|
-
rescue
|
39
|
-
puts error
|
38
|
+
rescue Errno::ENOENT, StandardError
|
40
39
|
if File.exists? @compress_file
|
41
40
|
File.unlink @compress_file
|
42
41
|
end
|
data/lib/oddb2xml/extractor.rb
CHANGED
@@ -23,7 +23,7 @@ module Oddb2xml
|
|
23
23
|
item[:name_fr] = (name = seq.at_xpath('.//NameFr')) ? name.text : ''
|
24
24
|
item[:org_gen_code] = (orgc = seq.at_xpath('.//OrgGenCode')) ? orgc.text : ''
|
25
25
|
item[:deductible] = (ddbl = seq.at_xpath('.//FlagSB20')) ? ddbl.text : ''
|
26
|
-
item[:atc_code] = (
|
26
|
+
item[:atc_code] = (atcc = seq.at_xpath('.//AtcCode')) ? atcc.text : ''
|
27
27
|
item[:comment_de] = (info = seq.at_xpath('.//CommentDe')) ? info.text : ''
|
28
28
|
item[:comment_fr] = (info = seq.at_xpath('.//CommentFr')) ? info.text : ''
|
29
29
|
item[:it_code] = ''
|
@@ -71,10 +71,25 @@ module Oddb2xml
|
|
71
71
|
# limitation
|
72
72
|
item[:packages][phar][:limitations] = []
|
73
73
|
pac.xpath('.//Limitation').each do |lim|
|
74
|
-
|
75
|
-
:
|
76
|
-
:
|
74
|
+
limitation = {
|
75
|
+
:it => item[:it_code],
|
76
|
+
:code => (lic = lim.at_xpath('.//LimitationCode')) ? lic.text : '',
|
77
|
+
:type => (lit = lim.at_xpath('.//LimitationType')) ? lit.text : '',
|
78
|
+
:value => (liv = lim.at_xpath('.//LimitationValue')) ? liv.text : '',
|
79
|
+
:desc_de => (dsc = lim.at_xpath('.//DescriptionDe')) ? dsc.text : '',
|
80
|
+
:desc_fr => (dsc = lim.at_xpath('.//DescriptionDe')) ? dsc.text : '',
|
81
|
+
:vdate => (dat = lim.at_xpath('.//ValidFromDate')) ? dat.text : '',
|
77
82
|
}
|
83
|
+
deleted = false
|
84
|
+
if upto = ((thr = lim.at_xpath('.//ValidThruDate')) ? thr.text : nil) and
|
85
|
+
upto =~ /\d{2}\.\d{2}\.\d{2}/
|
86
|
+
begin
|
87
|
+
deleted = true if Date.strptime(upto, '%d.%m.%y') >= Date.today
|
88
|
+
rescue ArgumentError
|
89
|
+
end
|
90
|
+
end
|
91
|
+
limitation[:del] = deleted
|
92
|
+
item[:packages][phar][:limitations] << limitation
|
78
93
|
end
|
79
94
|
# limitation points
|
80
95
|
pts = pac.at_xpath('.//PointLimitations/PointLimitation/Points') # only first points
|
data/lib/oddb2xml/version.rb
CHANGED
data/spec/compressor_spec.rb
CHANGED
@@ -7,6 +7,8 @@ shared_examples_for 'any compressor' do
|
|
7
7
|
File.stub(:unlink).and_return(false)
|
8
8
|
@compressor.contents << File.expand_path('../data/oddb_article.xml', __FILE__)
|
9
9
|
@compressor.contents << File.expand_path('../data/oddb_product.xml', __FILE__)
|
10
|
+
@compressor.contents << File.expand_path('../data/oddb_substance.xml', __FILE__)
|
11
|
+
@compressor.contents << File.expand_path('../data/oddb_limitation.xml', __FILE__)
|
10
12
|
@compressor.finalize!.should == true
|
11
13
|
compress_file = @compressor.instance_variable_get(:@compress_file)
|
12
14
|
File.exists?(compress_file).should == true
|
data/spec/downloader_spec.rb
CHANGED
@@ -84,4 +84,35 @@ describe Oddb2xml::SwissIndexDownloader do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
describe Oddb2xml::SwissmedicDownloader do
|
88
|
+
include ServerMockHelper
|
89
|
+
before(:each) do
|
90
|
+
setup_swissmedic_server_mock
|
91
|
+
@downloader = Oddb2xml::SwissmedicDownloader.new()
|
92
|
+
end
|
93
|
+
it_behaves_like 'any downloader'
|
94
|
+
context 'download_by for orphans xls' do
|
95
|
+
let(:io) { @downloader.download_by(:orphans) }
|
96
|
+
it 'should return valid IO' do
|
97
|
+
io.should be_a IO
|
98
|
+
io.bytes.should_not nil
|
99
|
+
end
|
100
|
+
it 'should clean up current directory' do
|
101
|
+
io.should_not raise_error(Timeout::Error)
|
102
|
+
File.exist?('oddb_orphans.xls').should be(false)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
context 'download_by for fridges xls' do
|
106
|
+
let(:io) { @downloader.download_by(:fridges) }
|
107
|
+
it 'should return valid IO' do
|
108
|
+
io.should be_a IO
|
109
|
+
io.bytes.should_not nil
|
110
|
+
end
|
111
|
+
it 'should clean up current directory' do
|
112
|
+
io.should_not raise_error(Timeout::Error)
|
113
|
+
File.exist?('oddb_fridges.xls').should be(false)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
87
118
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -19,12 +19,13 @@ module ServerMockHelper
|
|
19
19
|
def setup_server_mocks
|
20
20
|
setup_bag_xml_server_mock
|
21
21
|
setup_swiss_index_server_mock
|
22
|
+
setup_swissmedic_server_mock
|
22
23
|
end
|
23
24
|
def setup_bag_xml_server_mock
|
24
25
|
# zip
|
25
|
-
|
26
|
+
stub_zip_url = 'http://bag.e-mediat.net/SL2007.Web.External/File.axd?file=XMLPublications.zip'
|
26
27
|
stub_response = File.read(File.expand_path('../data/XMLPublications.zip', __FILE__))
|
27
|
-
stub_request(:get,
|
28
|
+
stub_request(:get, stub_zip_url).
|
28
29
|
with(:headers => {
|
29
30
|
'Accept' => '*/*',
|
30
31
|
'Accept-Encoding' => 'gzip,deflate,identity',
|
@@ -61,6 +62,39 @@ module ServerMockHelper
|
|
61
62
|
:body => stub_response)
|
62
63
|
end
|
63
64
|
end
|
65
|
+
def setup_swissmedic_server_mock
|
66
|
+
host = 'www.swissmedic.ch'
|
67
|
+
{
|
68
|
+
:orphans => {:html => '/daten/00081/index.html?lang=de', :xls => '/download'},
|
69
|
+
:fridges => {:html => '/daten/00080/00254/index.html?lang=de', :xls => '/download'}
|
70
|
+
}.each_pair do |type, urls|
|
71
|
+
# html (dummy)
|
72
|
+
stub_html_url = "http://#{host}" + urls[:html]
|
73
|
+
stub_response = File.read(File.expand_path("../data/swissmedic_#{type.to_s}.html", __FILE__))
|
74
|
+
stub_request(:get, stub_html_url).
|
75
|
+
with(:headers => {
|
76
|
+
'Accept' => '*/*',
|
77
|
+
'Host' => host,
|
78
|
+
}).
|
79
|
+
to_return(
|
80
|
+
:status => 200,
|
81
|
+
:headers => {'Content-Type' => 'text/html; charset=utf-8'},
|
82
|
+
:body => stub_response)
|
83
|
+
# xls
|
84
|
+
stub_xls_url = "http://#{host}" + urls[:xls] + "/swissmedic_#{type.to_s}.xls"
|
85
|
+
stub_response = File.read(File.expand_path("../data/swissmedic_#{type.to_s}.xls", __FILE__))
|
86
|
+
stub_request(:get, stub_xls_url).
|
87
|
+
with(:headers => {
|
88
|
+
'Accept' => '*/*',
|
89
|
+
'Accept-Encoding' => 'gzip,deflate,identity',
|
90
|
+
'Host' => host,
|
91
|
+
}).
|
92
|
+
to_return(
|
93
|
+
:status => 200,
|
94
|
+
:headers => {'Content-Type' => 'application/octet-stream; charset=utf-8'},
|
95
|
+
:body => stub_response)
|
96
|
+
end
|
97
|
+
end
|
64
98
|
end
|
65
99
|
|
66
100
|
RSpec.configure do |config|
|
metadata
CHANGED
@@ -1,63 +1,48 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: oddb2xml
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 10
|
10
|
-
version: 1.0.10
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Yasuhiro Asaka, Zeno R.R. Davatz
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-12-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: rdoc
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &11850420 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
18
|
+
requirements:
|
26
19
|
- - ~>
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 3
|
31
|
-
- 10
|
32
|
-
version: "3.10"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.10'
|
33
22
|
type: :development
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: hoe
|
37
23
|
prerelease: false
|
38
|
-
|
24
|
+
version_requirements: *11850420
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
requirement: &11849560 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
|
-
requirements:
|
29
|
+
requirements:
|
41
30
|
- - ~>
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
segments:
|
45
|
-
- 2
|
46
|
-
- 13
|
47
|
-
version: "2.13"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.13'
|
48
33
|
type: :development
|
49
|
-
|
50
|
-
|
51
|
-
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *11849560
|
36
|
+
description: ''
|
37
|
+
email:
|
52
38
|
- yasaka@ywesee.com, zdavatz@ywesee.com
|
53
|
-
executables:
|
39
|
+
executables:
|
54
40
|
- oddb2xml
|
55
41
|
extensions: []
|
56
|
-
|
57
|
-
extra_rdoc_files:
|
42
|
+
extra_rdoc_files:
|
58
43
|
- History.txt
|
59
44
|
- Manifest.txt
|
60
|
-
files:
|
45
|
+
files:
|
61
46
|
- .gitignore
|
62
47
|
- .rspec
|
63
48
|
- Gemfile
|
@@ -89,37 +74,28 @@ files:
|
|
89
74
|
- .gemtest
|
90
75
|
homepage:
|
91
76
|
licenses: []
|
92
|
-
|
93
77
|
post_install_message:
|
94
|
-
rdoc_options:
|
78
|
+
rdoc_options:
|
95
79
|
- --main
|
96
80
|
- README.txt
|
97
|
-
require_paths:
|
81
|
+
require_paths:
|
98
82
|
- lib
|
99
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
84
|
none: false
|
101
|
-
requirements:
|
102
|
-
- -
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
|
105
|
-
|
106
|
-
- 0
|
107
|
-
version: "0"
|
108
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
90
|
none: false
|
110
|
-
requirements:
|
111
|
-
- -
|
112
|
-
- !ruby/object:Gem::Version
|
113
|
-
|
114
|
-
segments:
|
115
|
-
- 0
|
116
|
-
version: "0"
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
117
95
|
requirements: []
|
118
|
-
|
119
96
|
rubyforge_project: oddb2xml
|
120
97
|
rubygems_version: 1.8.15
|
121
98
|
signing_key:
|
122
99
|
specification_version: 3
|
123
|
-
summary:
|
100
|
+
summary: ''
|
124
101
|
test_files: []
|
125
|
-
|