xdata 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ require_relative './xdata/util.rb'
2
+ require_relative './xdata/file_reader.rb'
3
+ require_relative './xdata/postcodes_4.rb'
4
+
5
+ module XData
6
+ VERSION = '0.1'
7
+ end
@@ -0,0 +1,677 @@
1
+ require 'csv'
2
+ require 'cgi'
3
+ require 'tmpdir'
4
+ require 'feedjira'
5
+ require 'geo_ruby'
6
+ require 'tempfile'
7
+ require 'geo_ruby/shp'
8
+ require 'geo_ruby/geojson'
9
+ require 'charlock_holmes'
10
+
11
+ require 'open-uri'
12
+
13
+ # wgs84_factory = RGeo::Geographic.spherical_factory(:srid => 4326, :proj4 => wgs84_proj4, :coord_sys => wgs84_wkt)
14
+
15
+ # feature = rd_factory.point(131712.93,456415.20)
16
+ # feature = RGeo::Feature.cast(feature,:factory => wgs84_factory, :project => true)
17
+
18
+ # factory = RGeo::Geographic.projected_factory(:projection_proj4 => '+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +units=m +no_defs ')
19
+ # rd_factory = RGeo::Geographic.spherical_factory(:srid => 28992, :proj4 => amersfoort-rd-new)
20
+ # curved_factory = RGeo::Geographic.spherical_factory(:srid => 4326)
21
+
22
+ module XData
23
+
24
+ class FileReader
25
+
26
+ RE_Y = /lat|(y.*coord)|(y.*pos.*)|(y.*loc(atie|ation)?)/i
27
+ RE_X = /lon|lng|(x.*coord)|(x.*pos.*)|(x.*loc(atie|ation)?)/i
28
+ RE_GEO = /^(geom(etry)?|location|locatie|coords|coordinates)$/i
29
+ RE_NAME = /(title|titel|naam|name)/i
30
+ RE_A_NAME = /^(naam|name|title|titel)$/i
31
+
32
+ attr_reader :file, :content,:params
33
+
34
+ def fillOut
35
+ @params[:rowcount] = @content.length
36
+ get_fields unless @params[:fields]
37
+ guess_name unless @params[:name]
38
+ guess_srid unless @params[:srid]
39
+ find_unique_field unless @params[:unique_id]
40
+ get_address unless @params[:hasaddress]
41
+ findExtends unless @params[:bounds]
42
+ end
43
+
44
+ def odata_json(url)
45
+ if url =~ /\/ODataFeed\//
46
+ uri = URI.parse(url)
47
+ return url + '?$format=json' if uri.query.nil?
48
+ pars = CGI.parse(uri.query)
49
+ return url if pars["$format"]
50
+ return url + '&$format=json'
51
+ end
52
+ return url
53
+ end
54
+
55
+ def download()
56
+ data = ''
57
+ if @params[:file_path] =~ /\/ODataFeed\//
58
+ open(odata_json(@params[:file_path])) do |f|
59
+ data = XData::parse_json(f.read)
60
+ read_json(nil,data)
61
+ end
62
+ else
63
+ open(@params[:file_path]) do |f|
64
+ data = f.read
65
+ end
66
+ if @params[:file_path] =~ /\.csv$/i
67
+ read_csv(nil,data)
68
+ elsif @params[:file_path] =~ /\.zip$/i
69
+ read_zip(nil,data)
70
+ elsif data =~ /^\s*<\?xml/
71
+ read_xml(nil,data)
72
+ else
73
+ begin
74
+ data = XData::parse_json(data)
75
+ read_json(nil,data)
76
+ rescue XData::Exception
77
+ return
78
+ end
79
+ end
80
+ end
81
+ fillOut
82
+ end
83
+
84
+
85
+ def initialize(pars)
86
+ @params = pars
87
+
88
+ if @params[:file_path] =~ /^http(s)?:\/\/.+/
89
+ download
90
+ else
91
+ file_path = File.expand_path(@params[:file_path])
92
+ if File.extname(file_path) == '.xdata'
93
+ read_xdata(file_path)
94
+ else
95
+ ext = @params[:originalfile] ? File.extname(@params[:originalfile]) : File.extname(file_path)
96
+ case ext
97
+ when /\.zip/i
98
+ read_zip(file_path)
99
+ when /\.(geo)?json/i
100
+ read_json(file_path)
101
+ when /\.shp/i
102
+ read_shapefile(file_path)
103
+ when /\.csv|tsv/i
104
+ read_csv(file_path)
105
+ when /\.xdata/i
106
+ read_xdata(file_path)
107
+ when /\.xml/i
108
+ read_xml(file_path)
109
+ else
110
+ raise "Unknown or unsupported file type: #{ext}."
111
+ end
112
+ end
113
+ end
114
+ fillOut
115
+ end
116
+
117
+ def get_address
118
+ pd = pc = hn = ad = false
119
+ @params[:housenumber] = nil
120
+ @params[:hasaddress] = 'unknown'
121
+ @params[:postcode] = nil
122
+ @params[:fields].reverse.each do |f|
123
+ pc = f if ( f.to_s =~ /^(post|zip|postal)code.*/i )
124
+ hn = f if ( f.to_s =~ /huisnummer|housenumber|(house|huis)(nr|no)|number/i)
125
+ ad = f if ( f.to_s =~ /address|street|straat|adres/i)
126
+ end
127
+ if pc and (ad or hn)
128
+ @params[:hasaddress] = 'certain'
129
+ end
130
+ @params[:postcode] = pc
131
+ @params[:housenumber] = hn ? hn : ad
132
+ end
133
+
134
+ def find_unique_field
135
+ fields = {}
136
+ @params[:unique_id] = nil
137
+ @content.each do |h|
138
+ h[:properties][:data].each do |k,v|
139
+ fields[k] = Hash.new(0) if fields[k].nil?
140
+ fields[k][v] += 1
141
+ end
142
+ end
143
+
144
+ fields.each_key do |k|
145
+ if fields[k].length == @params[:rowcount]
146
+ @params[:unique_id] = k
147
+ break
148
+ end
149
+ end
150
+
151
+ end
152
+
153
+ def guess_name
154
+ @params[:name] = nil
155
+ @params[:fields].reverse.each do |k|
156
+ if(k.to_s =~ RE_A_NAME)
157
+ @params[:name] = k
158
+ return
159
+ end
160
+ if(k.to_s =~ RE_NAME)
161
+ @params[:name] = k
162
+ end
163
+ end
164
+ end
165
+
166
+ def get_fields
167
+ @params[:fields] = []
168
+ @params[:alternate_fields] = {}
169
+ return if @content.blank?
170
+ @content[0][:properties][:data].each_key do |k|
171
+ k = (k.to_sym rescue k) || k
172
+ @params[:fields] << k
173
+ @params[:alternate_fields][k] = k
174
+ end
175
+ end
176
+
177
+ def guess_srid
178
+ return if @content.blank?
179
+ return unless @content[0][:geometry] and @content[0][:geometry].class == Hash
180
+ @params[:srid] = 4326
181
+ g = @content[0][:geometry][:coordinates]
182
+ if(g)
183
+ while g[0].is_a?(Array)
184
+ g = g[0]
185
+ end
186
+ lon = g[0]
187
+ lat = g[1]
188
+ if lon.between?(-7000.0,300000.0) and lat.between?(289000.0,629000.0)
189
+ # Simple minded check for Dutch new rd system
190
+ @params[:srid] = 28992
191
+ end
192
+ else
193
+
194
+ end
195
+ end
196
+
197
+ def find_col_sep(f)
198
+ a = f.gets
199
+ b = f.gets
200
+ [";","\t","|"].each do |s|
201
+ return s if (a.split(s).length == b.split(s).length) and b.split(s).length > 1
202
+ end
203
+ ','
204
+ end
205
+
206
+ def is_wkb_geometry?(s)
207
+ begin
208
+ f = GeoRuby::SimpleFeatures::GeometryFactory::new
209
+ p = GeoRuby::SimpleFeatures::HexEWKBParser.new(f)
210
+ p.parse(s)
211
+ g = f.geometry
212
+ return g.srid,g.as_json[:type],g
213
+ rescue => e
214
+ end
215
+ nil
216
+ end
217
+
218
+ def is_wkt_geometry?(s)
219
+ begin
220
+ f = GeoRuby::SimpleFeatures::GeometryFactory::new
221
+ p = GeoRuby::SimpleFeatures::EWKTParser.new(f)
222
+ p.parse(s)
223
+ g = f.geometry
224
+ return g.srid,g.as_json[:type],g
225
+ rescue => e
226
+ end
227
+ nil
228
+ end
229
+
230
+ GEOMETRIES = ["point", "multipoint", "linestring", "multilinestring", "polygon", "multipolygon"]
231
+ def is_geo_json?(s)
232
+ return nil if s.class != Hash
233
+ begin
234
+ if GEOMETRIES.include?(s[:type].downcase)
235
+ srid = 4326
236
+ if s[:crs] and s[:crs][:properties]
237
+ if s[:crs][:type] == 'OGC'
238
+ urn = s[:crs][:properties][:urn].split(':')
239
+ srid = urn.last.to_i if (urn[4] == 'EPSG')
240
+ elsif s[:crs][:type] == 'EPSG'
241
+ srid = s[:crs][:properties][:code]
242
+ end
243
+ end
244
+ return srid,s[:type],s
245
+ end
246
+ rescue Exception=>e
247
+ end
248
+ nil
249
+ end
250
+
251
+ def geom_from_text(coords)
252
+ # begin
253
+ # a = factory.parse_wkt(coords)
254
+ # rescue
255
+ # end
256
+
257
+ if coords =~ /^(\w+)(.+)/
258
+ if GEOMETRIES.include?($1.downcase)
259
+ type = $1.capitalize
260
+ coor = $2.gsub('(','[').gsub(')',']')
261
+ coor = coor.gsub(/([-+]?[0-9]*\.?[0-9]+)\s+([-+]?[0-9]*\.?[0-9]+)/) { "[#{$1},#{$2}]" }
262
+ coor = JSON.parse(coor)
263
+ return { :type => type,
264
+ :coordinates => coor }
265
+ end
266
+ end
267
+ {}
268
+ end
269
+
270
+ def findExtends
271
+ geometries = []
272
+ if @params[:hasgeometry]
273
+ @content.each do |o|
274
+ o[:geometry][:type] = 'MultiPolygon' if o[:geometry][:type] == 'Multipolygon'
275
+ geometries << Geometry.from_geojson(o[:geometry].to_json)
276
+ end
277
+ geom = GeometryCollection.from_geometries(geometries, (@params[:srid] || '4326'))
278
+ @params[:bounds] = XData.toPolygon(geom.bounding_box())
279
+ elsif @params[:postcode]
280
+ pc = @params[:postcode].to_sym
281
+ @content.each do |o|
282
+ p2 = PC4.lookup(o[:properties][:data][pc])
283
+ if p2
284
+ geometries << GeoRuby::SimpleFeatures::Point.from_coordinates(p2[0], (@params[:srid] || '4326'))
285
+ geometries << GeoRuby::SimpleFeatures::Point.from_coordinates(p2[1], (@params[:srid] || '4326'))
286
+ end
287
+ end
288
+ geom = GeometryCollection.from_geometries(geometries, (@params[:srid] || '4326'))
289
+ @params[:bounds] = XData.toPolygon(geom.bounding_box())
290
+ end
291
+ end
292
+
293
+
294
+ def find_geometry(xfield=nil, yfield=nil)
295
+ delete_column = (@params[:keep_geom] != true)
296
+ return if @content.blank?
297
+ unless(xfield and yfield)
298
+ @params[:hasgeometry] = nil
299
+ xs = true
300
+ ys = true
301
+
302
+ @content[0][:properties][:data].each do |k,v|
303
+ next if k.nil?
304
+
305
+ if k.to_s =~ RE_GEO
306
+ srid,g_type = is_wkb_geometry?(v)
307
+ if(srid)
308
+ @params[:srid] = srid
309
+ @params[:geometry_type] = g_type
310
+ @content.each do |h|
311
+ a,b,g = is_wkb_geometry?(h[:properties][:data][k])
312
+ h[:geometry] = g
313
+ h[:properties][:data].delete(k) if delete_column
314
+ end
315
+ @params[:hasgeometry] = k
316
+ return true
317
+ end
318
+
319
+ srid,g_type = is_wkt_geometry?(v)
320
+ if(srid)
321
+ @params[:srid] = srid
322
+ @params[:geometry_type] = g_type
323
+ @content.each do |h|
324
+ a,b,g = is_wkt_geometry?(h[:properties][:data][k])
325
+ h[:geometry] = g
326
+ h[:properties][:data].delete(k) if delete_column
327
+ end
328
+ @params[:hasgeometry] = k
329
+ return true
330
+ end
331
+
332
+ srid,g_type = is_geo_json?(v)
333
+ if(srid)
334
+ @params[:srid] = srid
335
+ @params[:geometry_type] = g_type
336
+ @content.each do |h|
337
+ h[:geometry] = h[:properties][:data][k]
338
+ h[:properties].delete(k) if delete_column
339
+ end
340
+ @params[:hasgeometry] = k
341
+ return true
342
+ end
343
+
344
+ end
345
+
346
+ hdc = k.to_s.downcase
347
+ if hdc == 'longitude' or hdc == 'lon' or hdc == 'x'
348
+ xfield=k; xs=false
349
+ end
350
+ if hdc == 'latitude' or hdc == 'lat' or hdc == 'y'
351
+ yfield=k; ys=false
352
+ end
353
+ xfield = k if xs and (hdc =~ RE_X)
354
+ yfield = k if ys and (hdc =~ RE_Y)
355
+ end
356
+ end
357
+
358
+ if xfield and yfield and (xfield != yfield)
359
+ @params[:hasgeometry] = [xfield,yfield]
360
+ @content.each do |h|
361
+ h[:properties][:data][xfield] = h[:properties][:data][xfield] || ''
362
+ h[:properties][:data][yfield] = h[:properties][:data][yfield] || ''
363
+ h[:geometry] = {:type => 'Point', :coordinates => [h[:properties][:data][xfield].gsub(',','.').to_f, h[:properties][:data][yfield].gsub(',','.').to_f]}
364
+ h[:properties][:data].delete(yfield) if delete_column
365
+ h[:properties][:data].delete(xfield) if delete_column
366
+ end
367
+ @params[:geometry_type] = 'Point'
368
+ @params[:fields].delete(xfield) if @params[:fields] and delete_column
369
+ @params[:fields].delete(yfield) if @params[:fields] and delete_column
370
+ return true
371
+ elsif (xfield and yfield)
372
+ # factory = ::RGeo::Cartesian.preferred_factory()
373
+ @params[:hasgeometry] = [xfield]
374
+ @content.each do |h|
375
+ h[:geometry] = geom_from_text(h[:properties][:data][xfield])
376
+ h[:properties][:data].delete(xfield) if h[:geometry] and delete_column
377
+ end
378
+ @params[:geometry_type] = ''
379
+ @params[:fields].delete(xfield) if @params[:fields] and delete_column
380
+ return true
381
+ end
382
+ false
383
+ end
384
+
385
+ def read_csv(path, c = nil)
386
+ if path
387
+ File.open(path, "r:bom|utf-8") do |fd|
388
+ c = fd.read
389
+ end
390
+ end
391
+
392
+ unless @params[:utf8_fixed]
393
+ detect = CharlockHolmes::EncodingDetector.detect(c)
394
+ c = CharlockHolmes::Converter.convert(c, detect[:encoding], 'UTF-8') if detect
395
+ end
396
+ c = c.force_encoding('utf-8')
397
+ c = c.gsub(/\r\n?/, "\n")
398
+ @content = []
399
+ @params[:colsep] = find_col_sep(StringIO.new(c)) unless @params[:colsep]
400
+ csv = CSV.new(c, :col_sep => @params[:colsep], :headers => true, :skip_blanks =>true)
401
+ csv.header_convert { |h| h.blank? ? '_' : h.strip.gsub(/\s+/,'_') }
402
+ csv.convert { |h| h ? h.strip : '' }
403
+ index = 0
404
+ begin
405
+ csv.each do |row|
406
+ r = row.to_hash
407
+ h = {}
408
+ r.each do |k,v|
409
+ h[(k.to_sym rescue k) || k] = v
410
+ end
411
+ @content << {properties: {data: h} }
412
+ index += 1
413
+ end
414
+ rescue => e
415
+ raise XData::Exception.new("Read CSV; line #{index}; #{e.message}")
416
+ end
417
+ find_geometry
418
+ end
419
+
420
+ def read_json(path, hash=nil)
421
+
422
+ STDERR.puts hash.class if hash
423
+
424
+ @content = []
425
+ if path
426
+ data = ''
427
+ File.open(path, "r:bom|utf-8") do |fd|
428
+ data = fd.read
429
+ end
430
+ hash = XData::parse_json(data)
431
+ end
432
+
433
+ if hash.is_a?(Hash) and hash[:'odata.metadata']
434
+ read_odata(hash)
435
+ elsif hash.is_a?(Hash) and hash[:type] and (hash[:type] == 'FeatureCollection')
436
+ # GeoJSON
437
+ hash[:features].each do |f|
438
+ f.delete(:type)
439
+ f[:properties] = {data: f[:properties]}
440
+ @content << f
441
+ end
442
+ @params[:hasgeometry] = 'GeoJSON'
443
+
444
+ else
445
+ # Free-form JSON
446
+ val,length = nil,0
447
+ if hash.is_a?(Array)
448
+ # one big array
449
+ val,length = hash,hash.length
450
+ else
451
+ hash.each do |k,v|
452
+ if v.is_a?(Array)
453
+ # the longest array value in the Object
454
+ val,length = v,v.length if v.length > length
455
+ end
456
+ end
457
+ end
458
+
459
+ if val
460
+ val.each do |h|
461
+ @content << { :properties => {:data => h} }
462
+ end
463
+ end
464
+ find_geometry
465
+ end
466
+ end
467
+
468
+ def srid_from_prj(str)
469
+ begin
470
+ connection = Faraday.new :url => "http://prj2epsg.org"
471
+ resp = connection.get('/search.json', {:mode => 'wkt', :terms => str})
472
+ if resp.status.between?(200, 299)
473
+ resp = XData::parse_json resp.body
474
+ @params[:srid] = resp[:codes][0][:code].to_i
475
+ end
476
+ rescue
477
+ end
478
+ end
479
+
480
+ def parseODataMeta(md)
481
+ @params[:md] = {} if @params[:md].nil?
482
+ @params[:md][:title] = md[:Title]
483
+ @params[:md][:identifier] = md[:Identifier]
484
+ @params[:md][:description] = md[:Description]
485
+ @params[:md][:abstract] = md[:ShortDescription]
486
+ @params[:md][:modified] = md[:Modified]
487
+ @params[:md][:temporal] = md[:Period]
488
+ @params[:md][:publisher] = md[:Source]
489
+ @params[:md][:accrualPeriodicity] = md[:Frequency]
490
+ @params[:md][:language] = md[:Language]
491
+ end
492
+
493
+ def parseODataFields(props)
494
+ rank=1
495
+ @params[:md] = {} if @params[:md].nil?
496
+ props.each do |p|
497
+ @params[:md]["fieldUnit.#{rank}".to_sym] = p[:Unit]
498
+ @params[:md]["fieldDescription.#{rank}".to_sym] = p[:Description]
499
+ @params[:md]["fieldLabel.#{rank}".to_sym] = p[:Key]
500
+ rank += 1
501
+ end
502
+ end
503
+
504
+ def read_odata(h)
505
+ @content = []
506
+ @params[:odata] = {}
507
+ links = h[:value]
508
+ links.each do |l|
509
+ @params[:odata][l[:name].to_sym] = l[:url]
510
+ end
511
+
512
+ begin
513
+ open(odata_json(@params[:odata][:TableInfos])) do |f|
514
+ md = XData::parse_json(f.read)[:value]
515
+ parseODataMeta(md[0])
516
+ end
517
+
518
+ open(odata_json(@params[:odata][:DataProperties])) do |f|
519
+ props = XData::parse_json(f.read)[:value]
520
+ parseODataFields(props)
521
+ end
522
+
523
+ open(odata_json(@params[:odata][:TypedDataSet])) do |f|
524
+ c = XData::parse_json(f.read)[:value]
525
+ c.each do |h|
526
+ @content << { :properties => {:data => h} }
527
+ end
528
+ end
529
+
530
+ rescue OpenURI::HTTPError => e
531
+ STDERR.puts e.message
532
+ end
533
+
534
+ find_geometry
535
+ end
536
+
537
+
538
+ def read_shapefile(path)
539
+
540
+ @content = []
541
+
542
+ prj = path.gsub(/.shp$/i,"") + '.prj'
543
+ prj = File.exists?(prj) ? File.read(prj) : nil
544
+ srid_from_prj(prj) if (prj and @params[:srid].nil?)
545
+
546
+ @params[:hasgeometry] = 'ESRI Shape'
547
+
548
+ GeoRuby::Shp4r::ShpFile.open(path) do |shp|
549
+ shp.each do |shape|
550
+ h = {}
551
+ h[:geometry] = XData::parse_json(shape.geometry.to_json) #a GeoRuby SimpleFeature
552
+ h[:properties] = {:data => {}}
553
+ att_data = shape.data #a Hash
554
+ shp.fields.each do |field|
555
+ s = att_data[field.name]
556
+ s = s.force_encoding('ISO8859-1') if s.class == String
557
+ h[:properties][:data][field.name.to_sym] = s
558
+ end
559
+ @content << h
560
+ end
561
+ end
562
+ end
563
+
564
+ def read_xml(path, data=nil)
565
+ if path
566
+ File.open(path, "r:bom|utf-8") do |fd|
567
+ data = fd.read
568
+ end
569
+ end
570
+ begin
571
+ feed = Feedjira::Feed.parse(data)
572
+ if feed
573
+ maxlat = -1000
574
+ maxlon = -1000
575
+ minlat = 1000
576
+ minlon = 1000
577
+ doc = Nokogiri::XML data
578
+ a = doc.xpath("//georss:polygon")
579
+ if a.length > 0
580
+ # geometries << GeoRuby::SimpleFeatures::Point..from_latlong(lat, lon)
581
+ a.each do |x|
582
+ # 50.6 3.1 50.6 7.3 53.7 7.3 53.7 3.1 50.6 3.1
583
+ s = x.text.split(/\s+/)
584
+ s.each_slice(2) { |c|
585
+ maxlat = [maxlat,c[0].to_f].max
586
+ maxlon = [maxlon,c[1].to_f].max
587
+ minlat = [minlat,c[0].to_f].min
588
+ minlon = [minlon,c[1].to_f].min
589
+ }
590
+ end
591
+ @params[:bounds] = { type: 'Polygon', coordinates: [[minlon,minlat], [minlon,maxlat], [maxlon,maxlat], [maxlon,minlat], [minlon,minlat]] }
592
+ end
593
+ end
594
+ # url = feed.entries[0].url
595
+ # Dir.mktmpdir("xdfi_#{File.basename(path).gsub(/\A/,'')}") do |dir|
596
+ # f = dir + '/' + File.basename(path)
597
+ # end
598
+ rescue Exception => e
599
+ puts e.inspect
600
+ return -1
601
+ end
602
+ end
603
+
604
+ def read_xdata(path)
605
+ h = Marshal.load(File.read(path))
606
+ @params = h[:config]
607
+ @content = h[:content]
608
+ end
609
+
610
+
611
+ def proces_zipped_dir(d)
612
+ Dir.foreach(d) do |f|
613
+
614
+ next if f =~ /^\./
615
+
616
+ if File.directory?(d + '/' + f)
617
+ return true if proces_zipped_dir(d + '/' + f)
618
+ end
619
+
620
+ case File.extname(f)
621
+ when /\.(geo)?json/i
622
+ read_json(d+'/'+f)
623
+ return true
624
+ when /\.shp/i
625
+ read_shapefile(d+'/'+f)
626
+ return true
627
+ when /\.csv|tsv/i
628
+ read_csv(d+'/'+f)
629
+ return true
630
+ end
631
+ end
632
+ return false
633
+ end
634
+
635
+ def read_zip(path, data=nil)
636
+ tempfile = nil
637
+ begin
638
+
639
+ if(data)
640
+ tempfile = Tempfile.new('xdatazip')
641
+ tempfile.write(data)
642
+ path = tempfile.path
643
+ end
644
+
645
+ Dir.mktmpdir("xdfi_#{File.basename(path).gsub(/\A/,'')}") do |dir|
646
+ command = "unzip '#{path}' -d '#{dir}' > /dev/null 2>&1"
647
+ raise XData::Exception.new("Error unzipping #{path}.", {:originalfile => path}, __FILE__, __LINE__) if not system command
648
+ if File.directory?(dir + '/' + File.basename(path).chomp(File.extname(path)))
649
+ dir = dir + '/' + File.basename(path).chomp(File.extname(path) )
650
+ end
651
+ return if proces_zipped_dir(dir)
652
+ end
653
+ rescue Exception => e
654
+ raise XData::Exception.new(e.message, {:originalfile => path}, __FILE__, __LINE__)
655
+ ensure
656
+ tempfile.unlink if tempfile
657
+ end
658
+ raise XData::Exception.new("Could not process file #{path}", {:originalfile => path}, __FILE__, __LINE__)
659
+ end
660
+
661
+ def write(path=nil)
662
+ path = @file_path if path.nil?
663
+ path = path + '.xdata'
664
+ begin
665
+ File.open(path,"w") do |fd|
666
+ fd.write( Marshal.dump({:config=>@params, :content=>@content}) )
667
+ end
668
+ rescue
669
+ return nil
670
+ end
671
+ return path
672
+ end
673
+
674
+ end
675
+
676
+ end
677
+