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.
@@ -1,3 +1,7 @@
1
+ === 1.1.0 / 27.12.2012
2
+
3
+ * Add new additional file limitation.xml
4
+
1
5
  === 1.0.10 / 25.12.2012
2
6
 
3
7
  * Add ORPH and COOL from swissmedic xls
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # oddb2xml
2
2
 
3
- oddb2xml, creates xml files using swissINDEX and BAG-XML.
3
+ oddb2xml, creates xml files using swissINDEX, BAG-XML and Swissmedic.
4
4
 
5
5
 
6
6
  ## usage
@@ -38,15 +38,32 @@ module Oddb2xml
38
38
  end
39
39
  end
40
40
  private
41
- def build_substance
42
- @substances = []
43
- @items.values.uniq.each do |seq|
44
- seq[:substances].each do |sub|
45
- @substances << sub[:name]
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
- @substances.uniq!
49
- @substances.sort!
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 = {
@@ -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
- @items = BagXmlExtractor.new(xml).to_hash
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
- if @options[:nonpharma]
118
- [:pharma, :nonpharma]
119
- else
120
- [:pharma]
121
- end
126
+ @_types ||=
127
+ if @options[:nonpharma]
128
+ [:pharma, :nonpharma]
129
+ else
130
+ [:pharma]
131
+ end
122
132
  end
123
133
  end
124
134
  end
@@ -14,7 +14,7 @@ module Oddb2xml
14
14
  super()
15
15
  end
16
16
  def finalize!
17
- unless @contents.select{ |file| File.exists?(file) }.length == 3
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 => error
39
- puts error
38
+ rescue Errno::ENOENT, StandardError
40
39
  if File.exists? @compress_file
41
40
  File.unlink @compress_file
42
41
  end
@@ -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] = (orgc = seq.at_xpath('.//AtcCode')) ? orgc.text : ''
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
- item[:packages][phar][:limitations] << {
75
- :code => (lic = lim.at_xpath('.//LimitationCode')) ? lic.text : '',
76
- :type => (lit = lim.at_xpath('.//LimitationType')) ? lit.text : '',
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
@@ -1,3 +1,3 @@
1
1
  module Oddb2xml
2
- VERSION = "1.0.10"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -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
@@ -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
@@ -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
- stub_wsdl_url = 'http://bag.e-mediat.net/SL2007.Web.External/File.axd?file=XMLPublications.zip'
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, stub_wsdl_url).
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
- hash: 3
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
- date: 2012-12-25 00:00:00 Z
19
- dependencies:
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
- prerelease: false
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
- hash: 19
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
- requirement: &id002 !ruby/object:Gem::Requirement
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
- hash: 25
44
- segments:
45
- - 2
46
- - 13
47
- version: "2.13"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.13'
48
33
  type: :development
49
- version_requirements: *id002
50
- description: ""
51
- email:
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
- hash: 3
105
- segments:
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
- hash: 3
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
-