oddb2xml 1.1.9 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,8 @@
1
+ === 1.2.0 / 22.01.2013
2
+
3
+ * Add dat format output
4
+ * Update file deletion on Windows
5
+
1
6
  === 1.1.9 / 17.01.2013
2
7
 
3
8
  * Improve SSLv3 Error message output
@@ -13,8 +13,10 @@ def help
13
13
  #$0 ver.#{Oddb2xml::VERSION}
14
14
  Usage:
15
15
  oddb2xml [option]
16
- -c F, --compress=F Compress format F. {tar.gz|zip}
17
16
  -a T, --append=T Additional target. T, only 'nonpharma' is available.
17
+ -c F, --compress=F Compress format F. {tar.gz|zip}
18
+ -f F, --format=F File format F, default is xml. {xml|dat}
19
+ If F is given, -o option is ignored.
18
20
  -o O, --optional=O Optional output. O, only 'fi' is available.
19
21
  -t S, --tag-suffix=S XML tag suffix S. Default is none. [A-z0-9_]
20
22
  If S is given, it is also used as prefix of filename.
@@ -24,15 +26,20 @@ end
24
26
 
25
27
  parser = OptionParser.new
26
28
  opts = {
27
- :compress_ext => nil,
28
29
  :nonpharma => false,
30
+ :compress_ext => nil,
31
+ :format => :xml,
32
+ :fi => false,
29
33
  :tag_suffix => nil,
34
+ :debug => false,
30
35
  }
31
36
 
32
- parser.on('-c v', '--compress v', /tar\.gz|zip/) {|v| opts[:compress_ext] = v }
33
37
  parser.on('-a v', '--append v', /nonpharma/) {|v| opts[:nonpharma] = true }
38
+ parser.on('-c v', '--compress v', /tar\.gz|zip/) {|v| opts[:compress_ext] = v }
39
+ parser.on('-f v', '--format v', /dat/) {|v| opts[:format] = :dat }
34
40
  parser.on('-o v', '--optional v', /fi/) {|v| opts[:fi] = true }
35
41
  parser.on('-t v', '--tag-suffix v', /^[A-z0-9_]*$/i) {|v| opts[:tag_suffix] = v.upcase }
42
+ #parser.on('--debug') {|v| opts[:debug] = true }
36
43
  parser.on_tail('-h', '--help') { puts help; exit }
37
44
 
38
45
  args = ARGV.dup
@@ -47,6 +54,7 @@ end
47
54
 
48
55
  ui = Oddb2xml::Cli.new(opts)
49
56
  begin
57
+ #puts opts if opts[:debug]
50
58
  ui.run
51
59
  rescue Interrupt
52
60
  puts
@@ -38,9 +38,16 @@ module Oddb2xml
38
38
  end
39
39
  def to_xml(subject=nil)
40
40
  if subject
41
- self.send('build_' + subject)
41
+ self.send('build_' + subject.to_s)
42
42
  elsif @subject
43
- self.send('build_' + @subject)
43
+ self.send('build_' + @subject.to_s)
44
+ end
45
+ end
46
+ def to_dat(subject=nil)
47
+ if subject
48
+ self.send('build_' + subject.to_s)
49
+ elsif @subject
50
+ self.send('build_' + @subject.to_s)
44
51
  end
45
52
  end
46
53
  private
@@ -679,5 +686,87 @@ module Oddb2xml
679
686
  end
680
687
  _builder.to_xml
681
688
  end
689
+
690
+ ### --- see oddb2tdat
691
+ def format_price(price_str, len=6, int_len=4, frac_len=2)
692
+ price = price_str.split('.')
693
+ pre = ''
694
+ las = ''
695
+ pre = "%0#{int_len}d" % (price[0] ? price[0] : '0')
696
+ las = if price[1]
697
+ if price[1].size < frac_len
698
+ price[1] + "0"*(frac_len-price[2].to_s.size)
699
+ else
700
+ price[1][0,frac_len]
701
+ end
702
+ else
703
+ '0'*frac_len
704
+ end
705
+ (pre.to_s + las.to_s)[0,len]
706
+ end
707
+ def format_date(date_str, len=7)
708
+ date = date_str.gsub('.','')
709
+ if date.size < len
710
+ date = date + '0'*(len-date.size)
711
+ end
712
+ date[0,len]
713
+ end
714
+ DAT_LEN = {
715
+ :RECA => 2,
716
+ :CMUT => 1,
717
+ :PHAR => 7,
718
+ :ABEZ => 50,
719
+ :PRMO => 6,
720
+ :PRPU => 6,
721
+ :CKZL => 1,
722
+ :CLAG => 1,
723
+ :CBGG => 1,
724
+ :CIKS => 1,
725
+ :ITHE => 7,
726
+ :CEAN => 13,
727
+ :CMWS => 1,
728
+ }
729
+ def build_dat
730
+ prepare_articles
731
+ rows = []
732
+ @articles.each do |obj|
733
+ row = ''
734
+ de_pac = obj[:de]
735
+ fr_pac = obj[:fr]
736
+ # Oddb2tdat.parse
737
+ if obj[:de][:status] =~ /A|I/
738
+ bg_pac = nil
739
+ if obj[:seq]
740
+ pac = obj[:seq][:packages][de_pac[:pharmacode]]
741
+ row << "%#{DAT_LEN[:RECA]}s" % '11'
742
+ row << "%#{DAT_LEN[:CMUT]}s" % if (phar = pac[:pharmacode] and phar.size > 3) # does not check expiration_date
743
+ obj[:de][:status] == "I" ? '3' : '1'
744
+ else
745
+ '3'
746
+ end
747
+ row << "%0#{DAT_LEN[:PHAR]}d" % pac[:pharmacode].to_i
748
+ row << "%-#{DAT_LEN[:ABEZ]}s" % (de_pac[:desc].to_s.gsub(/"/, '') + " " + pac[:name_de].to_s).to_s[0, DAT_LEN[:ABEZ]].gsub(/"/, '')
749
+ row << "%#{DAT_LEN[:PRMO]}s" % format_price(pac[:prices][:exf_price][:price].to_s)
750
+ row << "%#{DAT_LEN[:PRPU]}s" % format_price(pac[:prices][:pub_price][:price].to_s)
751
+ row << "%#{DAT_LEN[:CKZL]}s" % '3' # sl_entry and lppv
752
+ row << "%#{DAT_LEN[:CLAG]}s" % '0'
753
+ row << "%#{DAT_LEN[:CBGG]}s" % (pac[:narcosis_flag] == 'Y' ? '1' : '0')
754
+ row << "%#{DAT_LEN[:CIKS]}s" % if (pac[:swissmedic_category] =~ /^[ABCDE]$/)
755
+ pac[:swissmedic_category].gsub(/(\+|\s)/, '')
756
+ else
757
+ '0'
758
+ end
759
+ row << "%#{DAT_LEN[:ITHE]}s" % ' ' # ith_swissmedic
760
+ row << "%#{DAT_LEN[:CEAN]}s" % de_pac[:ean].to_s
761
+ row << "%#{DAT_LEN[:CMWS]}s" % '2'
762
+ rows << row
763
+ end
764
+ end
765
+ end
766
+ rows.join("\n")
767
+ end
768
+ def build_with_migel_dat
769
+ ''
770
+ end
682
771
  end
683
772
  end
@@ -29,35 +29,37 @@ module Oddb2xml
29
29
  def run
30
30
  threads = []
31
31
  # swissmedic-info
32
- if @options[:fi]
33
- threads << Thread.new do
34
- downloader = SwissmedicInfoDownloader.new
35
- xml = downloader.download
36
- @mutex.synchronize do
37
- hsh = SwissmedicInfoExtractor.new(xml).to_hash
38
- @infos = hsh
32
+ if @options[:format] != :dat
33
+ if @options[:fi]
34
+ threads << Thread.new do
35
+ downloader = SwissmedicInfoDownloader.new
36
+ xml = downloader.download
37
+ @mutex.synchronize do
38
+ hsh = SwissmedicInfoExtractor.new(xml).to_hash
39
+ @infos = hsh
40
+ end
39
41
  end
40
42
  end
41
- end
42
- # swissmedic
43
- [:orphans, :fridges].each do |type|
44
- threads << Thread.new do
45
- downloader = SwissmedicDownloader.new(type)
46
- bin = downloader.download
47
- self.instance_variable_set("@#{type.to_s}", SwissmedicExtractor.new(bin, type).to_arry)
43
+ # swissmedic
44
+ [:orphans, :fridges].each do |type|
45
+ threads << Thread.new do
46
+ downloader = SwissmedicDownloader.new(type)
47
+ bin = downloader.download
48
+ self.instance_variable_set("@#{type.to_s}", SwissmedicExtractor.new(bin, type).to_arry)
49
+ end
48
50
  end
49
- end
50
- # epha
51
- threads << Thread.new do
52
- downloader = EphaDownloader.new
53
- str = downloader.download
54
- @mutex.synchronize do
55
- @actions = EphaExtractor.new(str).to_arry
51
+ # epha
52
+ threads << Thread.new do
53
+ downloader = EphaDownloader.new
54
+ str = downloader.download
55
+ @mutex.synchronize do
56
+ @actions = EphaExtractor.new(str).to_arry
57
+ end
56
58
  end
57
59
  end
58
60
  # bag
59
61
  threads << Thread.new do
60
- downloader = BagXmlDownloader.new
62
+ downloader = BagXmlDownloader.new(@options)
61
63
  xml = downloader.download
62
64
  @mutex.synchronize do
63
65
  hsh = BagXmlExtractor.new(xml).to_hash
@@ -77,7 +79,7 @@ module Oddb2xml
77
79
  # swissindex
78
80
  types.each do |type|
79
81
  threads << Thread.new do
80
- downloader = SwissIndexDownloader.new(type, lang)
82
+ downloader = SwissIndexDownloader.new(@options, type, lang)
81
83
  begin
82
84
  xml = downloader.download
83
85
  rescue SystemExit
@@ -120,8 +122,15 @@ module Oddb2xml
120
122
  index = {}
121
123
  LANGUAGES.each do |lang|
122
124
  index[lang] = {} unless index[lang]
123
- types.each do |type|
124
- index[lang].merge!(@index[lang][type]) if @index[lang][type]
125
+ # TODO
126
+ # to fix @index structure
127
+ if @options[:format] == :dat
128
+ type = (sbj == :dat ? :pharma : :nonpharma)
129
+ index[lang] = @index[lang][type]
130
+ else
131
+ types.each do |type|
132
+ index[lang].merge!(@index[lang][type]) if @index[lang][type]
133
+ end
125
134
  end
126
135
  end
127
136
  builder.subject = sbj
@@ -136,8 +145,13 @@ module Oddb2xml
136
145
  builder.infos = @infos
137
146
  builder.tag_suffix = @options[:tag_suffix]
138
147
  end
139
- xml = builder.to_xml
140
- File.open(file, 'w:utf-8'){ |fh| fh << xml }
148
+ output = ''
149
+ if @options[:format] == :dat
150
+ output = builder.to_dat
151
+ else
152
+ output = builder.to_xml
153
+ end
154
+ File.open(file, 'w:utf-8'){ |fh| fh << output }
141
155
  end
142
156
  rescue Interrupt
143
157
  files.values.each do |file|
@@ -160,15 +174,22 @@ module Oddb2xml
160
174
  def files
161
175
  unless @_files
162
176
  @_files = {}
163
- ##
164
- # building order
165
- # 1. addtions
166
- # 2. subjects
167
- # 3. optionals
168
- _files = (ADDITIONS + SUBJECTS)
169
- _files += OPTIONALS if @options[:fi]
170
- _files.each do|sbj|
171
- @_files[sbj] = "#{prefix}_#{sbj.to_s}.xml"
177
+ if @options[:format] == :dat
178
+ @_files[:dat] = "#{prefix}.dat"
179
+ if @options[:nonpharma]
180
+ @_files[:with_migel_dat] = "#{prefix}_with_migel.dat"
181
+ end
182
+ else # xml
183
+ ##
184
+ # building order
185
+ # 1. addtions
186
+ # 2. subjects
187
+ # 3. optionals
188
+ _files = (ADDITIONS + SUBJECTS)
189
+ _files += OPTIONALS if @options[:fi]
190
+ _files.each do|sbj|
191
+ @_files[sbj] = "#{prefix}_#{sbj.to_s}.xml"
192
+ end
172
193
  end
173
194
  end
174
195
  @_files
@@ -6,7 +6,8 @@ require 'savon'
6
6
 
7
7
  module Oddb2xml
8
8
  class Downloader
9
- def initialize(url=nil)
9
+ def initialize(options={}, url=nil)
10
+ @options = options
10
11
  @url = url
11
12
  @retry_times = 3
12
13
  HTTPI.log = false # disable httpi warning
@@ -31,18 +32,21 @@ module Oddb2xml
31
32
  end
32
33
  def read_xml_form_zip(target, zipfile)
33
34
  xml = ''
34
- if RUBY_PLATFORM =~ /mswin|mingw|bccwin|cygwin/i # for memory error
35
- Zip::ZipFile.foreach(zipfile) do |entry|
36
- if entry.name =~ target
37
- io = entry.get_input_stream
38
- until io.eof?
39
- bytes = io.read(1024)
40
- xml << bytes
41
- bytes = nil
35
+ if RUBY_PLATFORM =~ /mswin|mingw|bccwin|cygwin/i
36
+ zip = ZipFile.open(zipfile) do |zipFile|
37
+ zipFile.each do |entry|
38
+ if entry.name =~ target
39
+ io = entry.get_input_stream
40
+ until io.eof?
41
+ bytes = io.read(1024)
42
+ xml << bytes
43
+ bytes = nil
44
+ end
45
+ io.close
42
46
  end
43
- io.close
44
47
  end
45
48
  end
49
+ zip.close
46
50
  else
47
51
  Zip::ZipFile.foreach(zipfile) do |entry|
48
52
  if entry.name =~ target
@@ -61,9 +65,13 @@ module Oddb2xml
61
65
  def download
62
66
  file = 'XMLPublications.zip'
63
67
  begin
64
- response = @agent.get(@url)
65
- response.save_as(file)
66
- response = nil # win
68
+ if @options[:debug]
69
+ FileUtils.copy(File.expand_path("../../../spec/data/#{file}", __FILE__), '.')
70
+ else
71
+ response = @agent.get(@url)
72
+ response.save_as(file)
73
+ response = nil # win
74
+ end
67
75
  return read_xml_form_zip(/^Preparation/iu, file)
68
76
  rescue Timeout::Error
69
77
  retrievable? ? retry : raise
@@ -75,11 +83,11 @@ module Oddb2xml
75
83
  end
76
84
  end
77
85
  class SwissIndexDownloader < Downloader
78
- def initialize(type=:pharma, lang='DE')
86
+ def initialize(options={}, type=:pharma, lang='DE')
79
87
  @type = (type == :pharma ? 'Pharma' : 'NonPharma')
80
88
  @lang = lang
81
89
  url = "https://index.ws.e-mediat.net/Swissindex/#{@type}/ws_#{@type}_V101.asmx?WSDL"
82
- super(url)
90
+ super(options, url)
83
91
  end
84
92
  def init
85
93
  config = {
@@ -93,6 +101,9 @@ module Oddb2xml
93
101
  end
94
102
  def download
95
103
  begin
104
+ if @options[:debug]
105
+ return File.read(File.expand_path("../../../spec/data/swissindex_#{@type}_#{@lang}.xml", __FILE__))
106
+ end
96
107
  soap = <<XML
97
108
  <?xml version="1.0" encoding="utf-8"?>
98
109
  <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
@@ -132,7 +143,7 @@ XML
132
143
  @xpath = "//table[@class='swmTableFlex']//a[@title='B3.1.35-d.xls']"
133
144
  end
134
145
  url = "http://www.swissmedic.ch/#{action}"
135
- super(url)
146
+ super({}, url)
136
147
  end
137
148
  def download
138
149
  file = "swissmedic_#{@type}.xls"
@@ -177,16 +188,24 @@ XML
177
188
  end
178
189
  if response
179
190
  response.save_as(file)
180
- response = nil # msmin
191
+ response = nil # win
181
192
  end
182
193
  return read_xml_form_zip(/^AipsDownload_/iu, file)
183
194
  rescue Timeout::Error
184
195
  retrievable? ? retry : raise
185
- rescue NoMethodError => e
196
+ rescue NoMethodError
186
197
  # pass
187
198
  ensure
199
+ # win
200
+ deleted = false
188
201
  if File.exists?(file)
189
- File.unlink(file)
202
+ until deleted
203
+ begin
204
+ File.unlink(file)
205
+ deleted = true
206
+ rescue Errno::EACCES # Permission Denied on Windows
207
+ end
208
+ end
190
209
  end
191
210
  end
192
211
  end
@@ -1,3 +1,3 @@
1
1
  module Oddb2xml
2
- VERSION = "1.1.9"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oddb2xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.9
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-17 00:00:00.000000000 Z
12
+ date: 2013-01-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rubyzip
16
- requirement: &16175640 !ruby/object:Gem::Requirement
16
+ requirement: &5831820 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *16175640
24
+ version_requirements: *5831820
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: archive-tar-minitar
27
- requirement: &16175000 !ruby/object:Gem::Requirement
27
+ requirement: &5829360 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *16175000
35
+ version_requirements: *5829360
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: mechanize
38
- requirement: &16174300 !ruby/object:Gem::Requirement
38
+ requirement: &5828680 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *16174300
46
+ version_requirements: *5828680
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: nokogiri
49
- requirement: &16173840 !ruby/object:Gem::Requirement
49
+ requirement: &5826640 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *16173840
57
+ version_requirements: *5826640
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: savon
60
- requirement: &16173260 !ruby/object:Gem::Requirement
60
+ requirement: &5826160 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '2.0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *16173260
68
+ version_requirements: *5826160
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: spreadsheet
71
- requirement: &16172800 !ruby/object:Gem::Requirement
71
+ requirement: &5825740 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *16172800
79
+ version_requirements: *5825740
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &16188540 !ruby/object:Gem::Requirement
82
+ requirement: &5825200 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *16188540
90
+ version_requirements: *5825200
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: webmock
93
- requirement: &16188000 !ruby/object:Gem::Requirement
93
+ requirement: &5841140 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *16188000
101
+ version_requirements: *5841140
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: ZenTest
104
- requirement: &16187540 !ruby/object:Gem::Requirement
104
+ requirement: &5840660 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *16187540
112
+ version_requirements: *5840660
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: hoe
115
- requirement: &16186660 !ruby/object:Gem::Requirement
115
+ requirement: &5840080 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: '3.4'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *16186660
123
+ version_requirements: *5840080
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: rdoc
126
- requirement: &16185900 !ruby/object:Gem::Requirement
126
+ requirement: &5839480 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,10 +131,10 @@ dependencies:
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *16185900
134
+ version_requirements: *5839480
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: rdoc
137
- requirement: &16185020 !ruby/object:Gem::Requirement
137
+ requirement: &5838700 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ~>
@@ -142,10 +142,10 @@ dependencies:
142
142
  version: '3.10'
143
143
  type: :development
144
144
  prerelease: false
145
- version_requirements: *16185020
145
+ version_requirements: *5838700
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: hoe
148
- requirement: &16184500 !ruby/object:Gem::Requirement
148
+ requirement: &5838200 !ruby/object:Gem::Requirement
149
149
  none: false
150
150
  requirements:
151
151
  - - ~>
@@ -153,7 +153,7 @@ dependencies:
153
153
  version: '2.13'
154
154
  type: :development
155
155
  prerelease: false
156
- version_requirements: *16184500
156
+ version_requirements: *5838200
157
157
  description: oddb2xml creates xml files using swissINDEX, BAG-XML and Swissmedic.
158
158
  email: yasaka@ywesee.com, zdavatz@ywesee.com
159
159
  executables: