oddb2xml 1.0.10 → 1.1.0

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