when_exe 0.3.4 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/locales.rb +2 -2
- data/bin/when.rb +2 -2
- data/lib/when_exe.rb +161 -55
- data/lib/when_exe/basictypes.rb +34 -26
- data/lib/when_exe/calendarnote.rb +654 -0
- data/lib/when_exe/calendartypes.rb +49 -474
- data/lib/when_exe/coordinates.rb +141 -34
- data/lib/when_exe/core/compatibility.rb +22 -2
- data/lib/when_exe/core/extension.rb +47 -3
- data/lib/when_exe/ephemeris.rb +82 -109
- data/lib/when_exe/googlecalendar.rb +1 -1
- data/lib/when_exe/icalendar.rb +26 -14
- data/lib/when_exe/inspect.rb +82 -68
- data/lib/when_exe/locales/af.rb +1 -1
- data/lib/when_exe/locales/ar.rb +1 -1
- data/lib/when_exe/locales/az.rb +1 -1
- data/lib/when_exe/locales/bg.rb +1 -1
- data/lib/when_exe/locales/bn.rb +1 -1
- data/lib/when_exe/locales/bs.rb +1 -1
- data/lib/when_exe/locales/ca.rb +1 -1
- data/lib/when_exe/locales/cs.rb +1 -1
- data/lib/when_exe/locales/cy.rb +1 -1
- data/lib/when_exe/locales/da.rb +1 -1
- data/lib/when_exe/locales/de.rb +1 -1
- data/lib/when_exe/locales/de_AT.rb +1 -1
- data/lib/when_exe/locales/de_CH.rb +1 -1
- data/lib/when_exe/locales/el.rb +1 -1
- data/lib/when_exe/locales/en.rb +1 -1
- data/lib/when_exe/locales/en_AU.rb +1 -1
- data/lib/when_exe/locales/en_CA.rb +1 -1
- data/lib/when_exe/locales/en_GB.rb +1 -1
- data/lib/when_exe/locales/en_IE.rb +1 -1
- data/lib/when_exe/locales/en_IN.rb +1 -1
- data/lib/when_exe/locales/en_NZ.rb +1 -1
- data/lib/when_exe/locales/en_US.rb +1 -1
- data/lib/when_exe/locales/eo.rb +1 -1
- data/lib/when_exe/locales/es.rb +1 -1
- data/lib/when_exe/locales/es_419.rb +1 -1
- data/lib/when_exe/locales/es_AR.rb +1 -1
- data/lib/when_exe/locales/es_CL.rb +1 -1
- data/lib/when_exe/locales/es_CO.rb +1 -1
- data/lib/when_exe/locales/es_CR.rb +1 -1
- data/lib/when_exe/locales/es_EC.rb +1 -1
- data/lib/when_exe/locales/es_MX.rb +1 -1
- data/lib/when_exe/locales/es_PA.rb +1 -1
- data/lib/when_exe/locales/es_PE.rb +1 -1
- data/lib/when_exe/locales/es_VE.rb +1 -1
- data/lib/when_exe/locales/et.rb +1 -1
- data/lib/when_exe/locales/eu.rb +1 -1
- data/lib/when_exe/locales/fa.rb +1 -1
- data/lib/when_exe/locales/fi.rb +1 -1
- data/lib/when_exe/locales/fr.rb +1 -1
- data/lib/when_exe/locales/fr_CA.rb +1 -1
- data/lib/when_exe/locales/fr_CH.rb +1 -1
- data/lib/when_exe/locales/gl.rb +1 -1
- data/lib/when_exe/locales/he.rb +1 -1
- data/lib/when_exe/locales/hi.rb +1 -1
- data/lib/when_exe/locales/hi_IN.rb +1 -1
- data/lib/when_exe/locales/hr.rb +1 -1
- data/lib/when_exe/locales/hu.rb +1 -1
- data/lib/when_exe/locales/id.rb +1 -1
- data/lib/when_exe/locales/is.rb +1 -1
- data/lib/when_exe/locales/it.rb +1 -1
- data/lib/when_exe/locales/it_CH.rb +1 -1
- data/lib/when_exe/locales/ja.rb +1 -1
- data/lib/when_exe/locales/kn.rb +1 -1
- data/lib/when_exe/locales/ko.rb +1 -1
- data/lib/when_exe/locales/lo.rb +1 -1
- data/lib/when_exe/locales/locales.rb +1 -1
- data/lib/when_exe/locales/lt.rb +1 -1
- data/lib/when_exe/locales/lv.rb +1 -1
- data/lib/when_exe/locales/mk.rb +1 -1
- data/lib/when_exe/locales/mn.rb +1 -1
- data/lib/when_exe/locales/ms.rb +1 -1
- data/lib/when_exe/locales/nb.rb +1 -1
- data/lib/when_exe/locales/ne.rb +1 -1
- data/lib/when_exe/locales/nl.rb +1 -1
- data/lib/when_exe/locales/nn.rb +1 -1
- data/lib/when_exe/locales/or.rb +1 -1
- data/lib/when_exe/locales/pl.rb +1 -1
- data/lib/when_exe/locales/pt.rb +1 -1
- data/lib/when_exe/locales/pt_BR.rb +1 -1
- data/lib/when_exe/locales/rm.rb +1 -1
- data/lib/when_exe/locales/ro.rb +1 -1
- data/lib/when_exe/locales/ru.rb +1 -1
- data/lib/when_exe/locales/sk.rb +1 -1
- data/lib/when_exe/locales/sl.rb +1 -1
- data/lib/when_exe/locales/sr.rb +1 -1
- data/lib/when_exe/locales/sv.rb +1 -1
- data/lib/when_exe/locales/sw.rb +1 -1
- data/lib/when_exe/locales/th.rb +1 -1
- data/lib/when_exe/locales/tl.rb +1 -1
- data/lib/when_exe/locales/tr.rb +1 -1
- data/lib/when_exe/locales/uk.rb +1 -1
- data/lib/when_exe/locales/ur.rb +1 -1
- data/lib/when_exe/locales/uz.rb +1 -1
- data/lib/when_exe/locales/vi.rb +1 -1
- data/lib/when_exe/locales/wo.rb +1 -1
- data/lib/when_exe/locales/zh_CN.rb +1 -1
- data/lib/when_exe/locales/zh_HK.rb +1 -1
- data/lib/when_exe/locales/zh_TW.rb +1 -1
- data/lib/when_exe/mini_application.rb +6 -2
- data/lib/when_exe/parts/enumerator.rb +13 -8
- data/lib/when_exe/parts/geometric_complex.rb +3 -5
- data/lib/when_exe/parts/locale.rb +185 -28
- data/lib/when_exe/parts/method_cash.rb +20 -10
- data/lib/when_exe/parts/resource.rb +154 -76
- data/lib/when_exe/parts/timezone.rb +11 -6
- data/lib/when_exe/region/bahai.rb +2 -2
- data/lib/when_exe/region/balinese.rb +296 -296
- data/lib/when_exe/region/chinese.rb +564 -564
- data/lib/when_exe/region/chinese_calendar.rb +5 -1
- data/lib/when_exe/region/chinese_epoch.rb +47 -102
- data/lib/when_exe/region/chinese_twin.rb +798 -0
- data/lib/when_exe/region/christian.rb +314 -338
- data/lib/when_exe/region/coptic.rb +88 -0
- data/lib/when_exe/region/ephemeric_notes.rb +322 -307
- data/lib/when_exe/region/french.rb +2 -2
- data/lib/when_exe/region/indian.rb +361 -272
- data/lib/when_exe/region/iranian.rb +2 -2
- data/lib/when_exe/region/islamic.rb +3 -3
- data/lib/when_exe/region/japanese.rb +1 -1
- data/lib/when_exe/region/japanese_notes.rb +165 -103
- data/lib/when_exe/region/japanese_residues.rb +56 -55
- data/lib/when_exe/region/japanese_twin.rb +228 -0
- data/lib/when_exe/region/javanese.rb +2 -2
- data/lib/when_exe/region/jewish.rb +2 -2
- data/lib/when_exe/region/korean.rb +4 -4
- data/lib/when_exe/region/m17n.rb +19 -19
- data/lib/when_exe/region/martian.rb +21 -9
- data/lib/when_exe/region/mayan.rb +19 -11
- data/lib/when_exe/region/moon.rb +7 -7
- data/lib/when_exe/region/nihon_shoki.rb +7 -7
- data/lib/when_exe/region/roman.rb +100 -100
- data/lib/when_exe/region/shire.rb +130 -147
- data/lib/when_exe/region/thai.rb +2 -2
- data/lib/when_exe/region/tibetan.rb +2 -2
- data/lib/when_exe/region/vietnamese.rb +383 -114
- data/lib/when_exe/region/world.rb +112 -129
- data/lib/when_exe/timestandard.rb +12 -1
- data/lib/when_exe/tmposition.rb +28 -14
- data/lib/when_exe/tmreference.rb +96 -93
- data/lib/when_exe/version.rb +1 -1
- data/test/examples/Terms.m17n +2 -2
- data/test/examples/sample.json +16 -0
- data/test/examples/sample.xml +1 -1
- data/test/test.rb +4 -0
- data/test/test/basictypes.rb +2 -2
- data/test/test/calendarnote.rb +69 -0
- data/test/test/calendartypes.rb +41 -1
- data/test/test/coordinates.rb +12 -1
- data/test/test/ephemeris.rb +13 -66
- data/test/test/icalendar.rb +3 -3
- data/test/test/inspect.rb +1 -1
- data/test/test/parts.rb +7 -4
- data/test/test/region/chinese.rb +45 -0
- data/test/test/region/coptic.rb +27 -0
- data/test/test/region/indian.rb +1 -1
- data/test/test/region/japanese.rb +4 -4
- data/test/test/region/jewish.rb +1 -1
- data/test/test/region/m17n.rb +7 -5
- data/test/test/region/residue.rb +2 -2
- data/test/test/region/vietnamese.rb +102 -0
- data/test/test/timestandard.rb +81 -0
- data/test/test/tmposition.rb +1 -1
- data/test/test/tmreference.rb +1 -1
- data/when_exe.gemspec +2 -2
- metadata +16 -7
@@ -257,13 +257,11 @@ module When::Parts
|
|
257
257
|
when GeometricComplex
|
258
258
|
@node = args[0].node
|
259
259
|
@reverse ^= args[0].reverse
|
260
|
-
super(self.first, self.last, exclude_end?)
|
261
|
-
return
|
260
|
+
return super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
|
262
261
|
|
263
262
|
when Array
|
264
263
|
@node = args[0]
|
265
|
-
super(self.first, self.last, exclude_end?)
|
266
|
-
return
|
264
|
+
return super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
|
267
265
|
|
268
266
|
when Range
|
269
267
|
first = [args[0].first, true]
|
@@ -288,7 +286,7 @@ module When::Parts
|
|
288
286
|
@node = []
|
289
287
|
@node << first if first
|
290
288
|
@node << last if last
|
291
|
-
super(self.first, self.last, exclude_end?)
|
289
|
+
super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
|
292
290
|
end
|
293
291
|
|
294
292
|
private
|
@@ -54,21 +54,47 @@ module When::Parts
|
|
54
54
|
"\\," => ","
|
55
55
|
}
|
56
56
|
|
57
|
+
# Wikipedia の URL の正規表現
|
58
|
+
# @private
|
59
|
+
Ref = /^http:\/\/(.+?)\.wikipedia\.org\/wiki\/([^#]+?)$/
|
60
|
+
|
61
|
+
# Wikipedia の多言語リンクの正規表現
|
62
|
+
# @private
|
63
|
+
Link = /<li class="interlanguage-link interwiki-(.+?)"><a href="\/\/(.+?)\.wikipedia\.org\/wiki\/(.+?)" title="(.+?) – /
|
64
|
+
|
57
65
|
class << self
|
58
66
|
|
67
|
+
# Wikipedia の連続的な参照を抑制するための遅延時間/秒
|
68
|
+
#
|
69
|
+
# @return [Numeric]
|
70
|
+
#
|
71
|
+
attr_accessor :wikipedia_interval
|
72
|
+
|
59
73
|
# When::Parts::Locale Module のグローバルな設定を行う
|
60
74
|
#
|
61
75
|
# @param [Hash] options 下記の通り
|
62
|
-
# @option options [Hash]
|
63
|
-
# @option options [Hash]
|
76
|
+
# @option options [Hash] :alias Locale の読み替えパターンを Hash で指定する。
|
77
|
+
# @option options [Hash] :unification 漢字の包摂パターンを Hash で指定する。
|
78
|
+
# @option options [Numeric] :wikipedia_interval Wikipedia の連続的な参照を抑制するための遅延時間/秒
|
64
79
|
#
|
65
80
|
# @note
|
66
81
|
# :alias の指定がない場合、aliases は DefaultAlias(モジュール定数)と解釈する。
|
67
82
|
# :unification の指定がない場合、unifications は DefaultUnification(モジュール定数)と解釈する。
|
68
83
|
#
|
69
84
|
def _setup_(options={})
|
70
|
-
@aliases
|
71
|
-
@unifications
|
85
|
+
@aliases = options[:alias] || DefaultAlias
|
86
|
+
@unifications = options[:unification] || DefaultUnification
|
87
|
+
@wikipedia_interval = options[:wikipedia_interval]
|
88
|
+
end
|
89
|
+
|
90
|
+
# 設定情報を取得する
|
91
|
+
#
|
92
|
+
# @return [Hash] 設定情報
|
93
|
+
#
|
94
|
+
def _setup_info
|
95
|
+
{:alias => _alias,
|
96
|
+
:unification => _unification,
|
97
|
+
:wikipedia_interval => @wikipedia_interval}
|
72
98
|
end
|
73
99
|
|
74
100
|
# 特定 locale に対応した文字列の取得
|
@@ -171,7 +197,7 @@ module When::Parts
|
|
171
197
|
if v.kind_of?(String)
|
172
198
|
v = v.strip
|
173
199
|
next if (v=~/^#/)
|
174
|
-
(v =~ /^(\*)?(.*?)(?:\s*=\s*(
|
200
|
+
(v =~ /^(\*)?(.*?)(?:\s*=\s*(.*))?$/) ? $~[1..3] : [[nil, '', nil]]
|
175
201
|
else
|
176
202
|
v
|
177
203
|
end
|
@@ -212,21 +238,118 @@ module When::Parts
|
|
212
238
|
def _hash_value(hash, locale, default='')
|
213
239
|
locale = locale.sub(/\..*/, '').sub(/-/,'_')
|
214
240
|
return hash[locale] if (hash[locale])
|
215
|
-
return _hash_value(hash, _alias[locale], default) if
|
241
|
+
return _hash_value(hash, _alias[locale], default) if _alias[locale]
|
216
242
|
language = locale.sub(/_.*/, '')
|
217
243
|
return hash[language] if (hash[language])
|
218
244
|
return hash[default]
|
219
245
|
end
|
220
246
|
|
247
|
+
# 漢字の包摂パターン
|
221
248
|
# @private
|
222
249
|
def _unification
|
223
|
-
@unifications
|
250
|
+
@unifications ||= DefaultUnification
|
224
251
|
end
|
225
252
|
|
253
|
+
private
|
254
|
+
|
255
|
+
# Locale の読み替えパターン
|
226
256
|
def _alias
|
227
|
-
@aliases
|
257
|
+
@aliases ||= DefaultAlias
|
258
|
+
end
|
259
|
+
|
260
|
+
# wikipedia オブジェクトの生成・参照
|
261
|
+
def wikipedia_object(path, options={})
|
262
|
+
query = options.delete(:query)
|
263
|
+
interval = options.key?(:interval) ? options.delete(:interval) : @wikipedia_interval
|
264
|
+
return nil unless Object.const_defined?(:JSON) && path =~ Ref
|
265
|
+
_wikipedia_relation(_wikipedia_object(path, $~[1], $~[2], query, interval, options), path, query)
|
266
|
+
end
|
267
|
+
|
268
|
+
# wikipedia の読み込み
|
269
|
+
def _wikipedia_object(path, locale, file, query, interval, options)
|
270
|
+
# 採取済みデータ
|
271
|
+
title = URI.decode(file.gsub('_', ' '))
|
272
|
+
mode = "".respond_to?(:force_encoding) ? ':utf-8' : ''
|
273
|
+
dir = Resource.root_dir + '/data/wikipedia/' + locale
|
274
|
+
FileUtils.mkdir_p(dir) unless FileTest.exist?(dir)
|
275
|
+
|
276
|
+
open("#{dir}/#{file}.json", 'r'+mode) do |source|
|
277
|
+
json = JSON.parse(source.read)
|
278
|
+
json.update(Hash[*query.split('&').map {|pair| pair.split('=')}.flatten]) if query
|
279
|
+
json.key?('names') ?
|
280
|
+
When::BasicTypes::M17n.new(json) :
|
281
|
+
When::Coordinates::Spatial.new(json)
|
282
|
+
end
|
283
|
+
|
284
|
+
rescue => no_file_error
|
285
|
+
# 新しいデータ
|
286
|
+
case interval
|
287
|
+
when 0
|
288
|
+
raise no_file_error
|
289
|
+
when Numeric
|
290
|
+
if @wikipedia_last_access
|
291
|
+
delay = (@wikipedia_last_access + interval.abs - Time.now.to_f).ceil
|
292
|
+
sleep(delay) if delay > 0
|
293
|
+
end
|
294
|
+
end
|
295
|
+
contents = nil
|
296
|
+
begin
|
297
|
+
OpenURI
|
298
|
+
source = open(path, 'r'+mode)
|
299
|
+
contents = source.read
|
300
|
+
ensure
|
301
|
+
@wikipedia_last_access = Time.now.to_f
|
302
|
+
source.close if source
|
303
|
+
end
|
304
|
+
|
305
|
+
# wikipedia contents
|
306
|
+
raise KeyError, 'Article not found: ' + title if contents =~ /<div class="noarticletext">/
|
307
|
+
|
308
|
+
# word
|
309
|
+
word = {
|
310
|
+
:label => title,
|
311
|
+
:names => {''=>title, locale=>title},
|
312
|
+
:link => {''=>path, locale=>path }
|
313
|
+
}
|
314
|
+
contents.scan(Link) do |link|
|
315
|
+
word[:names][$~[1]] = $~[4]
|
316
|
+
word[:link ][$~[1]] = "http://#{$~[1]}.wikipedia.org/wiki/#{$~[3]}"
|
317
|
+
end
|
318
|
+
object = When::BasicTypes::M17n.new(word)
|
319
|
+
|
320
|
+
# location
|
321
|
+
if contents =~ /tools\.wmflabs\.org\/geohack\/geohack\.php\?.+?params=(.+?[NS])_(.+?[EW])/
|
322
|
+
location = {
|
323
|
+
:label => object
|
324
|
+
}
|
325
|
+
location[:lat], location[:long] = $~[1..2].map {|pos|
|
326
|
+
pos.gsub(/_(\d)[._]/, '_0\1_').sub('.', '_').sub('_', '.').gsub('_', '')
|
327
|
+
}
|
328
|
+
object = When::Coordinates::Spatial.new(location)
|
329
|
+
end
|
330
|
+
|
331
|
+
# save data
|
332
|
+
open("#{dir}/#{file}.json", 'w'+mode) do |source|
|
333
|
+
source.write(JSON.dump(object.to_h({:method=>:to_h}).update(options)))
|
334
|
+
end
|
335
|
+
query ? _wikipedia_object(path, locale, file, query) : object
|
336
|
+
end
|
337
|
+
|
338
|
+
# wikipedia オブジェクトの関連付け
|
339
|
+
def _wikipedia_relation(object, path, query)
|
340
|
+
code_space = path.sub(/[^\/]+$/, '')
|
341
|
+
if object.kind_of?(When::Coordinates::Spatial)
|
342
|
+
object.label._pool['..'] = object
|
343
|
+
object._pool[object.label.to_s] = object.label
|
344
|
+
object.send(:child=, [object.label])
|
345
|
+
object.label.send(:code_space=, code_space)
|
346
|
+
else
|
347
|
+
object.send(:code_space=, code_space)
|
348
|
+
end
|
349
|
+
object._pool['..'] = path
|
350
|
+
object._pool['..'] += '?' + query if query
|
351
|
+
object
|
228
352
|
end
|
229
|
-
private :_alias
|
230
353
|
end
|
231
354
|
|
232
355
|
# ローケール指定時の文字列
|
@@ -343,12 +466,14 @@ module When::Parts
|
|
343
466
|
(@names.keys + other.names.keys).uniq.each do |key|
|
344
467
|
names[key] = _label_value(key) + other._label_value(key)
|
345
468
|
end
|
469
|
+
links = other.link
|
346
470
|
else
|
347
471
|
@names.keys.each do |key|
|
348
472
|
names[key] = _label_value(key) + other.to_s
|
349
473
|
end
|
474
|
+
links = {}
|
350
475
|
end
|
351
|
-
return dup._copy({:names=>names, :label=>to_s + other.to_s})
|
476
|
+
return dup._copy({:names=>names, :link=>links.merge(link), :label=>to_s + other.to_s})
|
352
477
|
end
|
353
478
|
|
354
479
|
# 書式指定による文字列化
|
@@ -387,11 +512,17 @@ module When::Parts
|
|
387
512
|
l
|
388
513
|
}
|
389
514
|
|
515
|
+
# link ハッシュ
|
516
|
+
links = terms.reverse.inject({}) {|h,t|
|
517
|
+
h.update(t.link) if t.kind_of?(Locale)
|
518
|
+
h
|
519
|
+
}
|
520
|
+
|
390
521
|
# 生成
|
391
|
-
# @private
|
392
522
|
dup._copy({
|
393
523
|
:label => keys.include?('') ? names.delete(nil) : (names[''] = names[keys[0]]),
|
394
|
-
:names => names
|
524
|
+
:names => names,
|
525
|
+
:link => links
|
395
526
|
})
|
396
527
|
end
|
397
528
|
alias :% :_printf
|
@@ -464,25 +595,35 @@ module When::Parts
|
|
464
595
|
|
465
596
|
# @private
|
466
597
|
def _copy(options={})
|
467
|
-
if
|
468
|
-
|
598
|
+
if options.key?('label') # for JSON
|
599
|
+
opt = {}
|
600
|
+
options.each_pair do |key, value|
|
601
|
+
opt[key.to_sym] = value
|
602
|
+
end
|
603
|
+
else
|
604
|
+
opt = options
|
605
|
+
end
|
606
|
+
|
607
|
+
self[0..-1] = opt[:label] if opt[:label]
|
608
|
+
if opt[:names]
|
609
|
+
@names = opt[:names]
|
469
610
|
@keys = @names.keys.sort
|
470
611
|
@values = @names.values.compact.sort.reverse
|
471
612
|
end
|
472
|
-
@
|
473
|
-
@
|
474
|
-
@access_key =
|
475
|
-
|
613
|
+
@label = opt[:label] if opt[:label]
|
614
|
+
@link = opt[:link] if opt[:link]
|
615
|
+
@access_key = opt[:access_key] if opt[:access_key]
|
616
|
+
@code_space = opt[:code_space] if opt[:code_space]
|
476
617
|
return self
|
477
618
|
end
|
478
619
|
|
479
620
|
# @private
|
480
621
|
def _copy_all(other)
|
481
|
-
_copy({:
|
622
|
+
_copy({:label => other.to_s,
|
623
|
+
:names => other.names,
|
482
624
|
:link => other.link,
|
483
|
-
:code_space => other.code_space,
|
484
625
|
:access_key => other.access_key,
|
485
|
-
:
|
626
|
+
:code_space => other.code_space
|
486
627
|
})
|
487
628
|
end
|
488
629
|
|
@@ -491,9 +632,12 @@ module When::Parts
|
|
491
632
|
def _label_value(locale)
|
492
633
|
label = Locale._hash_value(@names, locale, nil)
|
493
634
|
return label if label
|
494
|
-
|
495
|
-
return @names[''] unless
|
496
|
-
|
635
|
+
foreign = When::BasicTypes::M17n._get_locale(locale, @access_key)
|
636
|
+
return @names[''] unless foreign
|
637
|
+
english = @names['en'] || @names['']
|
638
|
+
addition = english.dup.sub!(/^#{When::BasicTypes::M17n._get_locale('en', @access_key)['en']}/, '')
|
639
|
+
foreign[locale] += addition if addition
|
640
|
+
update(foreign)
|
497
641
|
return Locale._hash_value(@names, locale)
|
498
642
|
end
|
499
643
|
|
@@ -505,7 +649,7 @@ module When::Parts
|
|
505
649
|
@names = {}
|
506
650
|
@link = {}
|
507
651
|
|
508
|
-
if
|
652
|
+
if names.kind_of?(String)
|
509
653
|
unless (names=~/\A\s*\[(.+?)\]\s*\z/m)
|
510
654
|
names = names.strip
|
511
655
|
@names[''] = names
|
@@ -524,7 +668,7 @@ module When::Parts
|
|
524
668
|
case v
|
525
669
|
when '', /^#/ ;
|
526
670
|
when /^\/(.+)/; @access_key = $1
|
527
|
-
when /^(\*)?(?:([^=%]*?)\s*:)?\s*(.+?)\s*(=\s*([^=]+?)?)?$/
|
671
|
+
when /^(\*)?(?:([^=%]*?)\s*:)?\s*(.+?)\s*(=\s*([^=]+?(\?.+)?)?)?$/
|
528
672
|
asterisk[0], locale, name, assignment, ref = $~[1..5]
|
529
673
|
asterisk[1], locale, default_ref = default_locale.shift unless locale
|
530
674
|
locale ||= ''
|
@@ -540,7 +684,19 @@ module When::Parts
|
|
540
684
|
end
|
541
685
|
ref += '%%<' + name + '>' if (ref =~ /[\/#:]$/)
|
542
686
|
@link[locale] = _encode(ref)
|
543
|
-
else ; raise ArgumentError, "Irregal locale format"
|
687
|
+
else ; raise ArgumentError, "Irregal locale format: " + v
|
688
|
+
end
|
689
|
+
end
|
690
|
+
if Locale.wikipedia_interval && Locale.wikipedia_interval <= 0
|
691
|
+
['en', ''].each do |lc|
|
692
|
+
if Locale::Ref =~ @link[lc] && $~[1] == 'en'
|
693
|
+
object = Locale.send(:wikipedia_object, @link[lc])
|
694
|
+
if object
|
695
|
+
@names = object.names.merge(@names)
|
696
|
+
@link = object.link.merge(@link)
|
697
|
+
end
|
698
|
+
break
|
699
|
+
end
|
544
700
|
end
|
545
701
|
end
|
546
702
|
|
@@ -548,7 +704,8 @@ module When::Parts
|
|
548
704
|
@keys = @names.keys.sort
|
549
705
|
@values = @names.values.sort.reverse
|
550
706
|
|
551
|
-
|
707
|
+
# 代表名
|
708
|
+
@names[mark[0] || mark[1] || mark[2]]
|
552
709
|
end
|
553
710
|
|
554
711
|
# encode URI from patterns %%(...) or %.(...)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
=begin
|
3
|
-
Copyright (C) 2011-
|
3
|
+
Copyright (C) 2011-2014 Takashi SUGA
|
4
4
|
|
5
5
|
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
6
6
|
=end
|
@@ -66,18 +66,20 @@ module When::Parts
|
|
66
66
|
|
67
67
|
# When::Parts::MethodCash のグローバルな設定を行う
|
68
68
|
#
|
69
|
-
# @param [
|
70
|
-
# @
|
71
|
-
# @
|
72
|
-
# @
|
69
|
+
# @param [Hash] options 以下の通り
|
70
|
+
# @option options [Boolean] :direct '_' で終わるメソッドをキャッシュせずに毎回計算するか否か
|
71
|
+
# @option options [Hash{Symbol=>boolean}] :escape 毎回 method_missing を発生させるメソッドを true にする
|
72
|
+
# @option options [false, nil] :escape to_str, to_ary, to_hash のみ毎回 method_missing を発生させる
|
73
|
+
# @option options [true] :escape すべて毎回 method_missing を発生させる
|
73
74
|
#
|
74
75
|
# @return [void]
|
75
76
|
#
|
76
|
-
# @note When::TM::Calendar クラスの一部はキャッシュ使用を前提としているため direct
|
77
|
+
# @note When::TM::Calendar クラスの一部はキャッシュ使用を前提としているため :direct=>true では動作しません
|
77
78
|
#
|
78
|
-
def _setup_(
|
79
|
-
@
|
80
|
-
|
79
|
+
def _setup_(options={})
|
80
|
+
@_setup_info = options
|
81
|
+
@direct = options[:direct]
|
82
|
+
case options[:escape]
|
81
83
|
when true
|
82
84
|
instance_eval %Q{
|
83
85
|
def escape(method)
|
@@ -85,7 +87,7 @@ module When::Parts
|
|
85
87
|
end
|
86
88
|
}
|
87
89
|
when Hash
|
88
|
-
@escape = Escape.merge(escape)
|
90
|
+
@escape = Escape.merge(options[:escape])
|
89
91
|
instance_eval %Q{
|
90
92
|
def escape(method)
|
91
93
|
@escape[method]
|
@@ -100,6 +102,14 @@ module When::Parts
|
|
100
102
|
end
|
101
103
|
end
|
102
104
|
|
105
|
+
# 設定情報を取得する
|
106
|
+
#
|
107
|
+
# @return [Hash] 設定情報
|
108
|
+
#
|
109
|
+
def _setup_info
|
110
|
+
@_setup_info ||= {}
|
111
|
+
end
|
112
|
+
|
103
113
|
# method_missing メソッドを forward するか否か
|
104
114
|
#
|
105
115
|
# @param [Symbol] method メソッドシンボル
|
@@ -143,7 +143,17 @@ module When::Parts
|
|
143
143
|
#
|
144
144
|
# @return [String]
|
145
145
|
#
|
146
|
-
|
146
|
+
def base_uri
|
147
|
+
@base_uri ||= When::SourceURI
|
148
|
+
end
|
149
|
+
|
150
|
+
# Root Directory for When_exe Resources
|
151
|
+
#
|
152
|
+
# @return [String]
|
153
|
+
#
|
154
|
+
def root_dir
|
155
|
+
@root_dir ||= When::RootDir
|
156
|
+
end
|
147
157
|
|
148
158
|
# @private
|
149
159
|
attr_reader :_prefix, :_prefix_values, :_prefix_index
|
@@ -151,7 +161,9 @@ module When::Parts
|
|
151
161
|
|
152
162
|
# 初期化
|
153
163
|
#
|
154
|
-
# @param [
|
164
|
+
# @param [Hash] options 以下の通り
|
165
|
+
# @option options [String] :base_uri Base URI for When_exe Resources (Default When::SourceURI)
|
166
|
+
# @option options [String] :root_dir Root Directory for When_exe Resources Cash data (Default When::RootDir)
|
155
167
|
#
|
156
168
|
# @return [void]
|
157
169
|
#
|
@@ -159,9 +171,10 @@ module When::Parts
|
|
159
171
|
# 本メソッドでマルチスレッド対応の管理変数の初期化を行っている。
|
160
172
|
# このため、本メソッド自体はスレッドセーフでない。
|
161
173
|
#
|
162
|
-
def _setup_(
|
174
|
+
def _setup_(options={})
|
163
175
|
super()
|
164
176
|
@_prefix = {
|
177
|
+
'_wp' => 'http://en.wikipedia.org/wiki/',
|
165
178
|
'_w' => base_uri + '/',
|
166
179
|
'_p' => base_uri + 'Parts/',
|
167
180
|
'_b' => base_uri + 'BasicTypes/',
|
@@ -176,14 +189,23 @@ module When::Parts
|
|
176
189
|
'_t' => base_uri + 'TimeStandard/',
|
177
190
|
'_ep' => base_uri + 'Ephemeris/',
|
178
191
|
'_c' => base_uri + 'CalendarTypes/',
|
179
|
-
'_n' => base_uri + '
|
192
|
+
'_n' => base_uri + 'CalendarNote/',
|
180
193
|
'_sc' => base_uri + 'Ephemeris/V50/'
|
181
194
|
}
|
182
|
-
@base_uri = base_uri
|
195
|
+
@base_uri = options[:base_uri] || When::SourceURI
|
196
|
+
@root_dir = options[:root_dir] || When::RootDir
|
183
197
|
@_prefix_values = @_prefix.values.sort.reverse
|
184
198
|
@_prefix_index = @_prefix.invert
|
185
199
|
end
|
186
200
|
|
201
|
+
# 設定情報を取得する
|
202
|
+
#
|
203
|
+
# @return [Hash] 設定情報
|
204
|
+
#
|
205
|
+
def _setup_info
|
206
|
+
{:base_uri => base_uri, :root_dir => root_dir}
|
207
|
+
end
|
208
|
+
|
187
209
|
# オブジェクト生成&参照
|
188
210
|
#
|
189
211
|
# 指定した iri の When::Parts::Resource オブジェクトを取得する。
|
@@ -225,13 +247,13 @@ module When::Parts
|
|
225
247
|
end
|
226
248
|
end
|
227
249
|
case @_pool[iri]
|
228
|
-
when my_mutex; my_mutex.synchronize {_create_object(iri, path, query) }
|
229
|
-
when Mutex ; @_pool[iri].synchronize {
|
250
|
+
when my_mutex; my_mutex.synchronize {@_pool[iri] = _create_object(iri, path, query) }
|
251
|
+
when Mutex ; @_pool[iri].synchronize {@_pool[iri]}
|
230
252
|
else ; @_pool[iri]
|
231
253
|
end
|
232
254
|
else
|
233
|
-
@_pool
|
234
|
-
@_pool[iri]
|
255
|
+
@_pool ||= {}
|
256
|
+
@_pool[iri] ||= _create_object(iri, path, query)
|
235
257
|
end
|
236
258
|
end
|
237
259
|
|
@@ -240,7 +262,11 @@ module When::Parts
|
|
240
262
|
_setup_ unless @_pool
|
241
263
|
path = obj.kind_of?(Class) ? obj.to_s.sub(/^When::/, base_uri).gsub(/::/, '/') :
|
242
264
|
obj.iri
|
243
|
-
|
265
|
+
simple ? _simplify_path(path) : path
|
266
|
+
end
|
267
|
+
|
268
|
+
# @private
|
269
|
+
def _simplify_path(path)
|
244
270
|
_prefix_values.each do |value|
|
245
271
|
index = path.index(value)
|
246
272
|
return _prefix_index[value] + ':' + path[value.length..-1] if index
|
@@ -294,10 +320,12 @@ module When::Parts
|
|
294
320
|
# @private
|
295
321
|
def _replace_tags(source, tags)
|
296
322
|
case source
|
323
|
+
when When::BasicTypes::M17n
|
324
|
+
source
|
297
325
|
when String
|
298
326
|
target = source.dup
|
299
327
|
tags.each_pair do |key, value|
|
300
|
-
target.gsub!(/#\{(
|
328
|
+
target.gsub!(/#\{([?&][^=#}]+?=)?#{key}(:.*?)?\}/, '\1' + value) if value.kind_of?(String)
|
301
329
|
end
|
302
330
|
target.gsub(/#\{.+?(:(.*?))?\}/, '\2')
|
303
331
|
when Array
|
@@ -305,7 +333,7 @@ module When::Parts
|
|
305
333
|
when Hash
|
306
334
|
target = {}
|
307
335
|
source.each_pair do |key, value|
|
308
|
-
target[key] =
|
336
|
+
target[key] = _replace_tags(tags[key] || value, tags)
|
309
337
|
end
|
310
338
|
target
|
311
339
|
else
|
@@ -344,9 +372,18 @@ module When::Parts
|
|
344
372
|
iri
|
345
373
|
end
|
346
374
|
|
375
|
+
# @private
|
376
|
+
def _instantiate(resource)
|
377
|
+
return resource unless resource.kind_of?(Array)
|
378
|
+
return resource[0].new(*resource[1..-1]) if resource[0].kind_of?(Class)
|
379
|
+
return resource.map {|rsc| _instantiate(rsc)}
|
380
|
+
end
|
381
|
+
|
347
382
|
private
|
348
383
|
|
384
|
+
# オブジェクト生成
|
349
385
|
def _create_object(iri, path, query)
|
386
|
+
# query analyzation
|
350
387
|
options = {}
|
351
388
|
replace = {}
|
352
389
|
if query
|
@@ -361,69 +398,48 @@ module When::Parts
|
|
361
398
|
end
|
362
399
|
options['..'] = iri
|
363
400
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
when Class
|
370
|
-
obj = list[0].new(options)
|
371
|
-
when Array
|
372
|
-
top = list[0][0]
|
373
|
-
if top.kind_of?(Hash)
|
374
|
-
top.each_pair do |key, value|
|
375
|
-
replace.update(value[replace.delete(key)]) if value.kind_of?(Hash) && value.key?(replace[key])
|
376
|
-
end
|
377
|
-
list[0] = list[0][1..-1]
|
378
|
-
list[0] = _replace_tags(list[0], top.merge(replace))
|
379
|
-
end
|
380
|
-
if list[0][0].kind_of?(Class)
|
381
|
-
# 配列の先頭がクラスである場合
|
382
|
-
klass, *list = list[0]
|
383
|
-
unless list[-1].kind_of?(Hash)
|
384
|
-
if list.length == 1
|
385
|
-
list[0] = {'.'=>Array(list[0])}
|
386
|
-
else
|
387
|
-
list << {}
|
388
|
-
end
|
389
|
-
end
|
390
|
-
else
|
391
|
-
# 配列の先頭がクラスではない場合
|
392
|
-
klass, *list = [list[1], *list[0]]
|
393
|
-
list << {} unless list[-1].kind_of?(Hash)
|
394
|
-
end
|
395
|
-
list[-1] = list[-1].merge(options)
|
396
|
-
obj = klass.new(*list)
|
401
|
+
# internal Resource
|
402
|
+
if path.index(Resource.base_uri) == 0
|
403
|
+
list = _class(path)
|
404
|
+
if list
|
405
|
+
return _internal(list, replace, options)
|
397
406
|
else
|
398
|
-
|
407
|
+
raise IOError, 'IRI not found - ' + path
|
399
408
|
end
|
400
|
-
|
401
|
-
|
402
|
-
|
409
|
+
end
|
410
|
+
|
411
|
+
# external Resource
|
412
|
+
begin
|
413
|
+
object = When::Parts::Locale.send(:wikipedia_object, path, {:query=>query})
|
414
|
+
return object if object
|
403
415
|
OpenURI
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
416
|
+
args = [path, "1".respond_to?(:force_encoding) ? 'r:utf-8' : 'r']
|
417
|
+
args << {:ssl_verify_mode=>OpenSSL::SSL::VERIFY_NONE} if path =~ /^https:/
|
418
|
+
open(*args) do |file|
|
419
|
+
resource = file.read
|
420
|
+
case resource[0..5].upcase
|
421
|
+
when 'BEGIN:'
|
422
|
+
options['.'] = _ics(_replace_tags(resource, replace).split(/[\n\r]+/))
|
423
|
+
options['.'][0].new(options)
|
424
|
+
when '<?XML '
|
425
|
+
options['.'] = _xml(REXML::Document.new(_replace_tags(resource, replace)).root)
|
426
|
+
options['.'][0].new(options)
|
427
|
+
else
|
428
|
+
raise NoMethodError, 'JSON not supported' unless Object.const_defined?(:JSON)
|
429
|
+
_internal(_json([JSON.parse(resource)]), replace, options)
|
411
430
|
end
|
412
|
-
rescue OpenURI::HTTPError => error
|
413
|
-
message = error.message + " - #{path}"
|
414
|
-
error = error.respond_to?(:uri) ?
|
415
|
-
error.class.new(message, error.io, error.uri) :
|
416
|
-
error.class.new(message, error.io)
|
417
|
-
raise error
|
418
431
|
end
|
419
|
-
|
420
|
-
|
432
|
+
rescue OpenURI::HTTPError => error
|
433
|
+
message = error.message + " - #{path}"
|
434
|
+
error = error.respond_to?(:uri) ?
|
435
|
+
error.class.new(message, error.io, error.uri) :
|
436
|
+
error.class.new(message, error.io)
|
437
|
+
raise error
|
421
438
|
end
|
422
|
-
@_pool[iri] = obj
|
423
439
|
end
|
424
440
|
|
441
|
+
# 内部形式定義の取得
|
425
442
|
def _class(path)
|
426
|
-
return nil unless path.index(Resource.base_uri) == 0
|
427
443
|
list = [When]
|
428
444
|
path[Resource.base_uri.length..-1].split(/\//).each do |mod|
|
429
445
|
if list[0].const_defined?(mod)
|
@@ -437,6 +453,42 @@ module When::Parts
|
|
437
453
|
return list
|
438
454
|
end
|
439
455
|
|
456
|
+
# 内部形式定義のオブジェクト化
|
457
|
+
def _internal(list, replace, options)
|
458
|
+
case list[0]
|
459
|
+
when Class
|
460
|
+
list[0].new(options)
|
461
|
+
when Array
|
462
|
+
top = list[0][0]
|
463
|
+
if top.kind_of?(Hash)
|
464
|
+
top.each_pair do |key, value|
|
465
|
+
replace.update(value[replace[key]]) if value.kind_of?(Hash) && value[replace[key]]
|
466
|
+
end
|
467
|
+
list[0] = list[0][1..-1]
|
468
|
+
list[0] = _replace_tags(list[0], top.merge(replace))
|
469
|
+
end
|
470
|
+
if list[0][0].kind_of?(Class)
|
471
|
+
# 配列の先頭がクラスである場合
|
472
|
+
klass, *list = list[0]
|
473
|
+
unless list[-1].kind_of?(Hash)
|
474
|
+
if list.length == 1
|
475
|
+
list[0] = {'.'=>Array(list[0])}
|
476
|
+
else
|
477
|
+
list << {}
|
478
|
+
end
|
479
|
+
end
|
480
|
+
else
|
481
|
+
# 配列の先頭がクラスではない場合
|
482
|
+
klass, *list = [list[1], *list[0]]
|
483
|
+
list << {} unless list[-1].kind_of?(Hash)
|
484
|
+
end
|
485
|
+
list[-1] = list[-1].merge(options)
|
486
|
+
klass.new(*list)
|
487
|
+
else
|
488
|
+
list[0]
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
440
492
|
# .xml フォーマットの読み込み
|
441
493
|
def _xml(xml, namespace={})
|
442
494
|
obj = [_class(_extract_prefix(xml.attributes['type'].to_s))[0]]
|
@@ -497,6 +549,27 @@ module When::Parts
|
|
497
549
|
end
|
498
550
|
raise ArgumentError, "BEGIN-END mismatch"
|
499
551
|
end
|
552
|
+
|
553
|
+
# .json フォーマットの読み込み
|
554
|
+
def _json(json)
|
555
|
+
case json
|
556
|
+
when Array
|
557
|
+
json.map {|value| _json(value)}
|
558
|
+
when Hash
|
559
|
+
hash = {}
|
560
|
+
json.each_pair {|key, value| hash[key] = _json(value)}
|
561
|
+
hash
|
562
|
+
when String
|
563
|
+
return json unless json =~ /^When::/
|
564
|
+
begin
|
565
|
+
return json.split('::').inject(Object) {|ns, sym| ns.const_get(sym)}
|
566
|
+
rescue
|
567
|
+
json
|
568
|
+
end
|
569
|
+
else
|
570
|
+
json
|
571
|
+
end
|
572
|
+
end
|
500
573
|
end
|
501
574
|
|
502
575
|
include Synchronize
|
@@ -508,7 +581,8 @@ module When::Parts
|
|
508
581
|
#
|
509
582
|
# @return [Array<When::Parts::Resource>]
|
510
583
|
#
|
511
|
-
|
584
|
+
attr_accessor :child
|
585
|
+
private :child=
|
512
586
|
|
513
587
|
#
|
514
588
|
# Resource包含階層で使用する namespace
|
@@ -539,17 +613,21 @@ module When::Parts
|
|
539
613
|
|
540
614
|
# オブジェクトの IRI
|
541
615
|
#
|
542
|
-
#
|
616
|
+
# @param [Boolean] prefix true ならIRI の先頭部分を簡約表現にする
|
617
|
+
#
|
618
|
+
# @return [Sring]
|
543
619
|
#
|
544
|
-
def iri
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
620
|
+
def iri(prefix=false)
|
621
|
+
unless @iri
|
622
|
+
root = @_pool['..']
|
623
|
+
path = root.instance_of?(String) ? root : label.to_s
|
624
|
+
if root.respond_to?(:iri)
|
625
|
+
root_iri = root.iri
|
626
|
+
path = root_iri + '::' + path if root_iri
|
627
|
+
end
|
628
|
+
@iri = path
|
551
629
|
end
|
552
|
-
@iri
|
630
|
+
prefix ? Resource._simplify_path(@iri) : @iri
|
553
631
|
end
|
554
632
|
|
555
633
|
# IRI または child の番号によるオブジェクト参照
|