oddb2xml 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in oddb2xml.gemspec
4
+ gemspec
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2012-09-17
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,14 @@
1
+ .gitignore
2
+ Gemfile
3
+ History.txt
4
+ Manifest.txt
5
+ README.md
6
+ Rakefile
7
+ bin/oddb2xml
8
+ lib/oddb2xml.rb
9
+ lib/oddb2xml/builder.rb
10
+ lib/oddb2xml/cli.rb
11
+ lib/oddb2xml/downloader.rb
12
+ lib/oddb2xml/extractor.rb
13
+ lib/oddb2xml/version.rb
14
+ oddb2xml.gemspec
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ oddb2xml
2
+ ========
3
+
4
+ oddb2xml, create xml files using swissINDEX and BAG-XML
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ # Hoe.plugin :compiler
7
+ # Hoe.plugin :gem_prelude_sucks
8
+ # Hoe.plugin :inline
9
+ # Hoe.plugin :minitest
10
+ # Hoe.plugin :racc
11
+ # Hoe.plugin :rubyforge
12
+
13
+ Hoe.spec 'oddb2xml' do
14
+
15
+ developer('Yasuhiro Asaka, Zeno R.R. Davatz', 'yasaka@ywesee.com, zdavatz@ywesee.com')
16
+
17
+ end
data/bin/oddb2xml ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ root = Pathname.new(__FILE__).realpath.parent.parent
6
+ $:.unshift root.join('lib') if $0 == __FILE__
7
+
8
+ require 'oddb2xml'
9
+
10
+ ui = Oddb2xml::Cli.new
11
+ unless ARGV.empty?
12
+ ui.help
13
+ else
14
+ begin
15
+ ui.run
16
+ rescue Interrupt
17
+ puts
18
+ exit
19
+ end
20
+ end
@@ -0,0 +1,318 @@
1
+ # encoding: utf-8
2
+
3
+ require 'nokogiri'
4
+
5
+ module Oddb2xml
6
+ class Builder
7
+ attr_accessor :subject, :index, :items
8
+ def initialize
9
+ @subject = nil
10
+ @index = {}
11
+ @items = {}
12
+ if block_given?
13
+ yield self
14
+ end
15
+ end
16
+ def to_xml
17
+ if @subject
18
+ self.send('build_' + @subject)
19
+ end
20
+ end
21
+ private
22
+ def build_product
23
+ # merge company info from swissINDEX
24
+ objects = []
25
+ objects = @items.values.uniq.map do |seq|
26
+ %w[de fr].each do |lang|
27
+ name_key = "company_name_#{lang}".intern
28
+ seq[name_key] = ''
29
+ if pharmacode = seq[:pharmacodes].first
30
+ indices = @index[lang.upcase]
31
+ if index = indices[pharmacode]
32
+ seq[name_key] = index[:company_name]
33
+ end
34
+ end
35
+ end
36
+ seq
37
+ end
38
+ _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
39
+ xml.PRODUCT(
40
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
41
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
42
+ 'xmlns' => 'http://wiki.oddb.org/wiki.php?pagename=Swissmedic.Datendeklaration',
43
+ 'CREATION_DATETIME' => Time.new.strftime('%FT%T.%7N%z'),
44
+ 'PROD_DATE' => '',
45
+ 'VALID_DATE' => ''
46
+ ) {
47
+ objects.each do |seq|
48
+ xml.PRD('DT' => '') {
49
+ xml.PRDNO seq[:product_key] unless seq[:product_key].empty?
50
+ %w[de fr].each do |l|
51
+ name = "name_#{l}".intern
52
+ desc = "desc_#{l}".intern
53
+ elem = "DSCR" + l[0].upcase
54
+ if !seq[name].empty? and !seq[desc].empty?
55
+ xml.send(elem, seq[name] + ' ' + seq[desc])
56
+ elsif !seq[desc].empty?
57
+ xml.send(elem, seq[desc])
58
+ end
59
+ end
60
+ #xml.BNAMD
61
+ #xml.BNAMF
62
+ #xml.ADNAMD
63
+ #xml.ADNAMF
64
+ #xml.SIZE
65
+ xml.ADINFD seq[:comment_de] unless seq[:comment_de].empty?
66
+ xml.ADINFF seq[:comment_fr] unless seq[:comment_fr].empty?
67
+ xml.GENCD seq[:org_gen_code] unless seq[:org_gen_code].empty?
68
+ #xml.GENGRP
69
+ xml.ATC seq[:atc_code] unless seq[:atc_code].empty?
70
+ xml.IT seq[:it_code] unless seq[:it_code].empty?
71
+ #xml.ITBAG
72
+ #xml.KONO
73
+ #xml.TRADE
74
+ #xml.PRTNO
75
+ #xml.MONO
76
+ #xml.CDGALD
77
+ #xml.CDGALF
78
+ #xml.FORMD
79
+ #xml.FORMF
80
+ #xml.DOSE
81
+ #xml.DOSEU
82
+ #xml.DRGFD
83
+ #xml.DRGFF
84
+ #xml.ORPH
85
+ #xml.BIOPHA
86
+ #xml.BIOSIM
87
+ #xml.BFS
88
+ #xml.BLOOD
89
+ #xml.MSCD # always empty
90
+ #xml.DEL
91
+ xml.CPT {
92
+ #xml.CPTLNO
93
+ #xml.CNAMED
94
+ #xml.CNAMEF
95
+ #xml.IDXIND
96
+ #xml.DDDD
97
+ #xml.DDDU
98
+ #xml.DDDA
99
+ #xml.IDXIA
100
+ #xml.IXREL
101
+ #xml.GALF
102
+ #xml.DRGGRPCD
103
+ #xml.PRBSUIT
104
+ #xml.CSOLV
105
+ #xml.CSOLVQ
106
+ #xml.CSOLVQU
107
+ #xml.PHVAL
108
+ #xml.LSPNSOL
109
+ #xml.APDURSOL
110
+ #xml.EXCIP
111
+ #xml.EXCIPQ
112
+ #xml.EXCIPCD
113
+ #xml.EXCIPCF
114
+ #xml.PQTY
115
+ #xml.PQTYU
116
+ #xml.SIZEMM
117
+ #xml.WEIGHT
118
+ #xml.LOOKD
119
+ #xml.LOOKF
120
+ #xml.IMG2
121
+ seq[:substances].each do |sub|
122
+ xml.CPTCMP {
123
+ xml.LINE sub[:index] unless sub[:index].empty?
124
+ #xml.SUBNO
125
+ xml.QTY sub[:quantity] unless sub[:quantity].empty?
126
+ xml.QTYU sub[:unit] unless sub[:unit].empty?
127
+ #xml.WHK
128
+ }
129
+ end
130
+ #xml.CPTIX {
131
+ #xml.IXNO
132
+ #xml.GRP
133
+ #xml.RLV
134
+ #}
135
+ #xml.CPTROA {
136
+ #xml.SYSLOC
137
+ #xml.ROA
138
+ #}
139
+ }
140
+ #xml.PRDICD { # currently empty
141
+ #xml.ICD
142
+ #xml.RTYP
143
+ #xml.RSIG
144
+ #xml.REMD
145
+ #xml.REMF
146
+ #}
147
+ }
148
+ end
149
+ xml.RESULT {
150
+ xml.OK_ERROR 'OK'
151
+ xml.NBR_RECORD objects.length.to_s
152
+ xml.ERROR_CODE ''
153
+ xml.MESSAGE ''
154
+ }
155
+ }
156
+ end
157
+ _builder.to_xml
158
+ end
159
+ def build_article
160
+ objects = [] # base is 'DE'
161
+ @index['DE'].each_pair do |pharmacode, index|
162
+ object = {
163
+ :de => index,
164
+ :fr => @index['FR'][pharmacode],
165
+ }
166
+ if seq = @items[pharmacode]
167
+ object[:seq] = seq
168
+ end
169
+ objects << object
170
+ end
171
+ _builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
172
+ xml.ARTICLE(
173
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
174
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
175
+ 'xmlns' => 'http://wiki.oddb.org/wiki.php?pagename=Swissmedic.Datendeklaration',
176
+ 'CREATION_DATETIME' => Time.new.strftime('%FT%T.%7N%z'),
177
+ 'PROD_DATE' => '',
178
+ 'VALID_DATE' => ''
179
+ ) {
180
+ objects.each do |obj|
181
+ de_pac = obj[:de] # swiss index DE (base)
182
+ fr_pac = obj[:fr] # swiss index FR
183
+ bg_pac = nil # BAG XML (additional data)
184
+ if obj[:seq]
185
+ bg_pac = obj[:seq][:packages][de_pac[:pharmacode]]
186
+ end
187
+ xml.ART('DT' => '') {
188
+ xml.PHAR de_pac[:pharmacode] unless de_pac[:pharmacode].empty?
189
+ #xml.GRPCD
190
+ #xml.CDS01
191
+ #xml.CDS02
192
+ if obj[:seq]
193
+ xml.PRDNO obj[:seq][:product_key] unless obj[:seq][:product_key].empty?
194
+ end
195
+ if bg_pac
196
+ xml.SMCAT bg_pac[:swissmedic_category] unless bg_pac[:swissmedic_category].empty?
197
+ xml.SMNO bg_pac[:swissmedic_number] unless bg_pac[:swissmedic_number].empty?
198
+ end
199
+ #xml.HOSPCD
200
+ #xml.CLINCD
201
+ #xml.ARTTYP
202
+ #xml.VAT
203
+ #xml.SALECD
204
+ if bg_pac
205
+ #xml.INSLIM
206
+ xml.LIMPTS bg_pac[:limitation_points] unless bg_pac[:limitation_points].empty?
207
+ end
208
+ #xml.GRDFR
209
+ #xml.COOL
210
+ #xml.TEMP
211
+ #xml.CDBG
212
+ #xml.BG
213
+ #xml.EXP
214
+ xml.QTY de_pac[:additional_desc] unless de_pac[:additional_desc].empty?
215
+ xml.DSCRD de_pac[:desc] unless de_pac[:desc].empty?
216
+ xml.DSCRF fr_pac[:desc] unless fr_pac[:desc].empty?
217
+ xml.SORTD de_pac[:desc].upcase unless de_pac[:desc].empty?
218
+ xml.SORTF fr_pac[:desc].upcase unless fr_pac[:desc].empty?
219
+ #xml.QTYUD
220
+ #xml.QTYUF
221
+ #xml.IMG
222
+ #xml.IMG2
223
+ #xml.PCKTYPD
224
+ #xml.PCKTYPF
225
+ #xml.MULT
226
+ if obj[:seq]
227
+ xml.SYN1D obj[:seq][:name_de] unless obj[:seq][:name_de].empty?
228
+ xml.SYN1F obj[:seq][:name_fr] unless obj[:seq][:name_fr].empty?
229
+ end
230
+ #xml.SLOPLUS
231
+ #xml.NOPCS
232
+ #xml.HSCD
233
+ #xml.MINI
234
+ #xml.DEPCD
235
+ #xml.DEPOT
236
+ #xml.BAGSL
237
+ #xml.BAGSLC
238
+ #xml.LOACD
239
+ if de_pac[:status] == "I"
240
+ xml.OUTSAL de_pac[:stat_date] unless de_pac[:stat_date].empty?
241
+ end
242
+ #xml.STTOX
243
+ #xml.NOTI
244
+ #xml.GGL
245
+ #xml.CE
246
+ #xml.SMDAT
247
+ #xml.SMCDAT
248
+ #xml.SIST
249
+ #xml.ESIST
250
+ #xml.BIOCID
251
+ #xml.BAGNO
252
+ #xml.LIGHT
253
+ #xml.DEL
254
+ xml.ARTCOMP {
255
+ # use ean13(gln) as COMPNO
256
+ xml.COMPNO de_pac[:company_ean] unless de_pac[:company_ean].empty?
257
+ #xml.ROLE
258
+ #xml.ARTNO1
259
+ #xml.ARTNO2
260
+ #xml.ARTNO3
261
+ }
262
+ xml.ARTBAR {
263
+ xml.CDTYP 'E13'
264
+ xml.BC de_pac[:ean] unless de_pac[:ean].empty?
265
+ xml.BCSTAT 'A' # P is alternative
266
+ #xml.PHAR2
267
+ }
268
+ #xml.ARTCH {
269
+ #xml.PHAR2
270
+ #xml.CHTYPE
271
+ #xml.LINENO
272
+ #xml.NOUNITS
273
+ #}
274
+ if bg_pac
275
+ bg_pac[:prices].each_pair do |key, price|
276
+ xml.ARTPRI {
277
+ xml.VDAT price[:valid_date] unless price[:valid_date].empty?
278
+ xml.PTYP price[:price_code] unless price[:price_code].empty?
279
+ xml.PRICE price[:price] unless price[:price].empty?
280
+ }
281
+ end
282
+ end
283
+ #xml.ARTMIG {
284
+ #xml.VDAT
285
+ #xml.MIGCD
286
+ #xml.LINENO
287
+ #}
288
+ #xml.ARTDAN {
289
+ #xml.CDTYP
290
+ #xml.LINENO
291
+ #xml.CDVAL
292
+ #}
293
+ if bg_pac
294
+ bg_pac[:limitations].each do |lim|
295
+ xml.ARTLIM {
296
+ xml.LIMCD lim[:code] unless lim[:code].empty?
297
+ }
298
+ end
299
+ end
300
+ #xml.ARTINS {
301
+ #xml.VDAT
302
+ #xml.INCD
303
+ #xml.NINCD
304
+ #}
305
+ }
306
+ end
307
+ xml.RESULT {
308
+ xml.OK_ERROR 'OK'
309
+ xml.NBR_RECORD objects.length.to_s
310
+ xml.ERROR_CODE ''
311
+ xml.MESSAGE ''
312
+ }
313
+ }
314
+ end
315
+ _builder.to_xml
316
+ end
317
+ end
318
+ end
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+
3
+ require 'thread'
4
+ require 'oddb2xml/builder'
5
+ require 'oddb2xml/downloader'
6
+ require 'oddb2xml/extractor'
7
+
8
+ module Oddb2xml
9
+ class Cli
10
+ SUBJECTS = %w[product article]
11
+ LANGUAGES = %w[DE FR] # EN does not exist
12
+ def initialize
13
+ #@mutex = Mutex.new
14
+ @items = {} # Preparations.xml in BAG
15
+ @index = {}
16
+ LANGUAGES.each do |lang|
17
+ @index[lang] = {} # swissINDEX
18
+ end
19
+ end
20
+ def help
21
+ puts <<EOS
22
+ #$0 ver.#{Oddb2xml::VERSION}
23
+ Usage:
24
+ oddb2xml
25
+ EOS
26
+ end
27
+ def run
28
+ # Sometimes nokogiri crashes with ruby in Threads.
29
+ #threads = []
30
+ # bag_xml
31
+ #threads << Thread.new do
32
+ downloader = BagXmlDownloader.new
33
+ xml = downloader.download
34
+ extractor = BagXmlExtractor.new(xml)
35
+ @items = extractor.to_hash
36
+ #end
37
+ LANGUAGES.map do |lang|
38
+ # swissindex
39
+ #threads << Thread.new do
40
+ downloader = SwissIndexDownloader.new
41
+ xml = downloader.download_by(lang)
42
+ extractor = SwissIndexExtractor.new(xml)
43
+ index = extractor.to_hash
44
+ #@mutex.synchronize do
45
+ @index["#{lang}"] = index
46
+ #end
47
+ #end
48
+ end
49
+ #threads.map(&:join)
50
+ build
51
+ report
52
+ end
53
+ private
54
+ def build
55
+ files = {}
56
+ SUBJECTS.each{ |sbj| files[sbj] = "oddb_#{sbj}.xml" }
57
+ begin
58
+ files.each_pair do |sbj, file|
59
+ builder = Builder.new do |builder|
60
+ builder.subject = sbj
61
+ builder.index = @index
62
+ builder.items = @items
63
+ end
64
+ xml = builder.to_xml
65
+ File.open(file, 'w:utf-8'){ |fh| fh << xml }
66
+ end
67
+ rescue Interrupt
68
+ files.values.each do |file|
69
+ if File.exist? file
70
+ File.unlink file
71
+ end
72
+ end
73
+ raise Interrupt
74
+ end
75
+ end
76
+ def report
77
+ # pass
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,94 @@
1
+ # encoding: utf-8
2
+
3
+ require 'mechanize'
4
+ require 'zip/zip'
5
+ require 'savon'
6
+
7
+ module Oddb2xml
8
+ class Downloader
9
+ def initialize(url=nil)
10
+ @url = url
11
+ @retry_times = 3
12
+ HTTPI.log = false # disable httpi warning
13
+ init
14
+ end
15
+ def init
16
+ # pass
17
+ end
18
+ protected
19
+ def retrievable?
20
+ if @retry_times > 0
21
+ sleep 5
22
+ @retry_times -= 1
23
+ true
24
+ else
25
+ false
26
+ end
27
+ end
28
+ end
29
+ class BagXmlDownloader < Downloader
30
+ def init
31
+ @url ||= 'http://bag.e-mediat.net/SL2007.Web.External/File.axd?file=XMLPublications.zip'
32
+ end
33
+ def download
34
+ file = 'XMLPublications.zip'
35
+ begin
36
+ response = Mechanize.new.get(@url)
37
+ response.save_as file
38
+ xml = ''
39
+ Zip::ZipFile.foreach(file) do |entry|
40
+ if entry.name =~ /^Preparation/iu
41
+ entry.get_input_stream{ |io| xml = io.read }
42
+ end
43
+ end
44
+ return xml
45
+ rescue Timeout::Error
46
+ retrievable? ? retry : raise
47
+ ensure
48
+ if File.exists? file
49
+ File.unlink file
50
+ end
51
+ end
52
+ end
53
+ end
54
+ class SwissIndexDownloader < Downloader
55
+ def init
56
+ @url ||= 'https://index.ws.e-mediat.net/Swissindex/Pharma/ws_Pharma_V101.asmx?WSDL'
57
+ Savon.configure do |config|
58
+ config.log_level = :info
59
+ config.log = false # $stdout
60
+ config.raise_errors = true
61
+ end
62
+ end
63
+ def download_by(lang = 'DE')
64
+ client = Savon::Client.new do |wsdl, http|
65
+ http.auth.ssl.verify_mode = :none
66
+ wsdl.document = @url
67
+ end
68
+ begin
69
+ response = client.request :download_all do
70
+ soap.xml = <<XML
71
+ <?xml version="1.0" encoding="utf-8"?>
72
+ <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/">
73
+ <soap:Body>
74
+ <lang xmlns="http://swissindex.e-mediat.net/SwissindexPharma_out_V101">#{lang}</lang>
75
+ </soap:Body>
76
+ </soap:Envelope>
77
+ XML
78
+ end
79
+ if response.success?
80
+ if xml = response.to_xml
81
+ return xml
82
+ else
83
+ # received broken data or internal error
84
+ raise StandardError
85
+ end
86
+ else
87
+ raise Timeout::Error
88
+ end
89
+ rescue Timeout::Error
90
+ retrievable? ? retry : raise
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,122 @@
1
+ # encoding: utf-8
2
+
3
+ require 'nokogiri'
4
+
5
+ module Oddb2xml
6
+ class Extractor
7
+ attr_accessor :xml
8
+ def initialize(xml)
9
+ @xml = xml
10
+ end
11
+ end
12
+ class BagXmlExtractor < Extractor
13
+ def to_hash
14
+ #File.open('../bagxml.xml', 'r:ASCII-8BIT') do |f|
15
+ # @xml = f.read
16
+ #end
17
+ # pharmacode => sequence
18
+ data = {}
19
+ doc = Nokogiri::XML(@xml)
20
+ doc.xpath('//Preparation').each do |seq|
21
+ item = {}
22
+ item[:product_key] = seq.attr('ProductCommercial').to_s
23
+ item[:desc_de] = (desc = seq.at_xpath('.//DescriptionDe')) ? desc.text : ''
24
+ item[:desc_fr] = (desc = seq.at_xpath('.//DescriptionFr')) ? desc.text : ''
25
+ item[:name_de] = (name = seq.at_xpath('.//NameDe')) ? name.text : ''
26
+ item[:name_fr] = (name = seq.at_xpath('.//NameFr')) ? name.text : ''
27
+ item[:org_gen_code] = (orgc = seq.at_xpath('.//OrgGenCode')) ? orgc.text : ''
28
+ item[:atc_code] = (orgc = seq.at_xpath('.//AtcCode')) ? orgc.text : ''
29
+ item[:comment_de] = (info = seq.at_xpath('.//CommentDe')) ? info.text : ''
30
+ item[:comment_fr] = (info = seq.at_xpath('.//CommentFr')) ? info.text : ''
31
+ item[:it_code] = ''
32
+ seq.xpath('.//ItCode').each do |itc|
33
+ if item[:it_code].to_s.empty?
34
+ it_code = itc.attr('Code').to_s
35
+ item[:it_code] = (it_code =~ /(\d+)\.(\d+)\.(\d+)./) ? it_code : ''
36
+ end
37
+ end
38
+ item[:substances] = []
39
+ seq.xpath('.//Substance').each_with_index do |sub, i|
40
+ item[:substances] << {
41
+ :index => i.to_s,
42
+ :quantity => (qtty = sub.at_xpath('.//Quantity')) ? qtty.text : '',
43
+ :unit => (unit = sub.at_xpath('.//QuantityUnit')) ? unit.text : '',
44
+ }
45
+ end
46
+ item[:pharmacodes] = []
47
+ item[:packages] = {} # pharmacode => package
48
+ seq.xpath('.//Pack').each do |pac|
49
+ if phar = pac.attr('Pharmacode')
50
+ phar = phar.to_s
51
+ # as common key with swissINDEX
52
+ item[:pharmacodes] << phar
53
+ # packages
54
+ item[:packages][phar] = {
55
+ :pharmacode => phar,
56
+ :swissmedic_category => (cat = pac.at_xpath('.//SwissmedicCategory')) ? cat.text : '',
57
+ :swissmedic_number => (num = pac.at_xpath('.//SwissmedicNo8')) ? num.text : '',
58
+ :narcosis_flag => (flg = pac.at_xpath('.//FlagNarcosis')) ? flg.text : '',
59
+ :prices => {
60
+ :exf_price => {
61
+ :price => (exf = pac.at_xpath('.//ExFactoryPrice/Price')) ? exf.text : '',
62
+ :valid_date => (exf = pac.at_xpath('.//ExFactoryPrice/ValidFromDate')) ? exf.text : '',
63
+ :price_code => (exf = pac.at_xpath('.//ExFactoryPrice/PriceTypeCode')) ? exf.text : '',
64
+ },
65
+ :pub_price => {
66
+ :price => (pub = pac.at_xpath('.//PublicPrice/Price')) ? pub.text : '',
67
+ :valid_date => (pub = pac.at_xpath('.//PublicPrice/ValidFromDate')) ? pub.text : '',
68
+ :price_code => (pub = pac.at_xpath('.//PublicPrice/PriceTypeCode')) ? pub.text : '',
69
+ }
70
+ }
71
+ }
72
+ # limitation
73
+ item[:packages][phar][:limitations] = []
74
+ pac.xpath('.//Limitation').each do |lim|
75
+ item[:packages][phar][:limitations] << {
76
+ :code => (lic = lim.at_xpath('.//LimitationCode')) ? lic.text : '',
77
+ :type => (lit = lim.at_xpath('.//LimitationType')) ? lit.text : '',
78
+ }
79
+ end
80
+ # limitation points
81
+ pts = pac.at_xpath('.//PointLimitations/PointLimitation/Points') # only first points
82
+ item[:packages][phar][:limitation_points] = pts ? pts.text : ''
83
+ # pharmacode => seq (same data)
84
+ data[phar] = item
85
+ end
86
+ end
87
+ end
88
+ data
89
+ end
90
+ end
91
+ class SwissIndexExtractor < Extractor
92
+ def to_hash
93
+ #File.open('../swissindex.xml', 'r:ASCII-8BIT') do |f|
94
+ # @xml = f.read
95
+ #end
96
+ # pharmacode => package
97
+ data = {}
98
+ doc = Nokogiri::XML(@xml)
99
+ doc.remove_namespaces!
100
+ doc.xpath('//Envelope/Body/PHARMA/ITEM').each do |pac|
101
+ item = {}
102
+ item[:ean] = (gtin = pac.at_xpath('.//GTIN')) ? gtin.text : ''
103
+ item[:pharmacode] = (phar = pac.at_xpath('.//PHAR')) ? phar.text : ''
104
+ item[:status] = (stat = pac.at_xpath('.//STATUS')) ? stat.text : ''
105
+ item[:stat_date] = (date = pac.at_xpath('.//SDATE')) ? date.text : ''
106
+ item[:lang] = (lang = pac.at_xpath('.//LANG')) ? lang.text : ''
107
+ item[:desc] = (dscr = pac.at_xpath('.//DSCR')) ? dscr.text : ''
108
+ item[:atc_code] = (code = pac.at_xpath('.//ATC')) ? code.text : ''
109
+ # as quantity text
110
+ item[:additional_desc] = (dscr = pac.at_xpath('.//ADDSCR')) ? dscr.text : ''
111
+ if comp = pac.xpath('.//COMP')
112
+ item[:company_name] = (nam = comp.at_xpath('.//NAME')) ? nam.text : ''
113
+ item[:company_ean] = (gln = comp.at_xpath('.//GLN')) ? gln.text : ''
114
+ end
115
+ unless item[:pharmacode].empty?
116
+ data[item[:pharmacode]] = item
117
+ end
118
+ end
119
+ data
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,3 @@
1
+ module Oddb2xml
2
+ VERSION = "0.0.1"
3
+ end
data/lib/oddb2xml.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "oddb2xml/version"
2
+ require 'oddb2xml/cli'
3
+
4
+ module Oddb2xml
5
+ end
data/oddb2xml.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'oddb2xml/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "oddb2xml"
8
+ gem.version = Oddb2xml::VERSION
9
+ gem.authors = [""]
10
+ gem.email = [""]
11
+ gem.description = %q{TODO: Write a gem description}
12
+ gem.summary = %q{TODO: Write a gem summary}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'rubyzip'
21
+ gem.add_dependency 'mechanize'
22
+ gem.add_dependency 'nokogiri'
23
+ gem.add_dependency 'savon'
24
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oddb2xml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yasuhiro Asaka, Zeno R.R. Davatz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rdoc
16
+ requirement: &8627820 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.10'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *8627820
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ requirement: &8627320 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '2.13'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *8627320
36
+ description: ''
37
+ email:
38
+ - yasaka@ywesee.com, zdavatz@ywesee.com
39
+ executables:
40
+ - oddb2xml
41
+ extensions: []
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ files:
46
+ - .gitignore
47
+ - Gemfile
48
+ - History.txt
49
+ - Manifest.txt
50
+ - README.md
51
+ - Rakefile
52
+ - bin/oddb2xml
53
+ - lib/oddb2xml.rb
54
+ - lib/oddb2xml/builder.rb
55
+ - lib/oddb2xml/cli.rb
56
+ - lib/oddb2xml/downloader.rb
57
+ - lib/oddb2xml/extractor.rb
58
+ - lib/oddb2xml/version.rb
59
+ - oddb2xml.gemspec
60
+ homepage:
61
+ licenses: []
62
+ post_install_message:
63
+ rdoc_options:
64
+ - --main
65
+ - README.txt
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project: oddb2xml
82
+ rubygems_version: 1.8.15
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: ''
86
+ test_files: []