oddb2xml 1.0.10 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|