File: weather.rb

package info (click to toggle)
tdiary 5.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,088 kB
  • sloc: ruby: 23,031; javascript: 1,029; xml: 325; makefile: 26; sh: 4
file content (409 lines) | stat: -rw-r--r-- 19,672 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
=begin
= その日の天気プラグイン((-$Id: weather.rb,v 1.13 2008-03-02 09:01:46 kazuhiko Exp $-))
その日の天気を、その日の日記を最初に更新する時に取得して保存し、それぞれ
の日の日記の上部に表示します。

== 入手方法
このファイルの最新版は、
((<URL:http://zunda.freeshell.org/d/plugin/weather.rb>))
にあります。

== 使い方
=== インストールと設定の方法
このファイルをpluginディレクトリにコピーしてください。漢字コードは
EUC-JPです。

次に、tdiary.confを編集するか、WWWブラウザからtDiaryの設定画面から「その
日の天気」を選んで、天気データをいただいてくるURLを設定してください。
tdiary.confを編集する場合には、@options['weather.url']に設定してくださ
い。両方で設定をした場合には、tDiaryの設定画面での設定が優先されます。

例えば、 NOAA National Weather Serviceを利用する場合には、
((<URL:http://weather.noaa.gov/>))から、Select a country...で国名を選ん
でGo!ボタンを押し、次に観測地点を選んでください。その時表示されたページ
のURLを、例えば、
  @options['weather.url'] = 'http://weather.noaa.gov/weather/current/RJTI.html'
と書いてください。この例では東京ヘリポート((-どこにあるんだろ?-))の天気
が記録されます。情報の二次利用が制限されている場合がありますので、そのよ
うなWWWページから情報を取得しないように注意してください。

さらに、将来日記のタイムゾーンが変化する可能性がある方は、今のタイムゾー
ンを、@options['weather.tz']か、環境変数TZに設定しておくことをお勧めし
ます。これによって、日記が引越した後も、天気データ取得時のタイムゾーン
で天気を表示し続けることができます。tdiary.confに設定する場合は、例えば
日本標準時の場合は、
  @options['weather.tz'] = 'Japan'
と設定してください。

これで、新しい日の日記を書く度に、設定したURLから天候データを取得して、
表示するようになるはずです。天気は、
  <div class="weather"><span class="weather">hh:mm現在<a href="取得元URL">天気(温度)</a></span></div>
という形式でそれぞれの日の日記の上に表示されます。必要ならば、CSSを編集
してください。
  div.weather {
    text-align: right;
    font-size: 75%;
  }
などとしておけばいいでしょう。

日記に使用しているWWWサーバーからサーバーの権限でWWWページの閲覧ができる
必要があります。mod_rubyでの動作は今のところ確認していません。

デフォルトでは、携帯端末から閲覧された場合には天気を表示しないようになっ
ています。携帯からでも天気を表示したい場合には、設定画面から設定するか、
tdiary.confに
  @options['weather.show_mobile'] = true
を指定してください。

=== 保存される天気データについて
天気データは、
* 書いてる日記の日付と現在の日付が一致し、
* その日の天気データがまだ取得されていないか、前回の取得時にエラーがあった
場合に、取得されます。

天気データは、@options['weather.dir']に設定したディレクトリか、
@cache_path/weather/ ディレクトリ以下に、年/年月.weather というファイ ル
名で保存されます。タブ区切りのテキストファイルですので必要に応じて編集
することができます。タブの数を変えてしまわないように気をつけて編集してく
ださい。フォーマットの詳細は、Weather.to_sメソッドを参照してください。

天気データには、データの取得時刻が記録されています。また、データの取得元
から得られた、天気の更新時刻が記録されていることもあります。これらの時刻
は、世界標準時(UNIX時刻)に直されて記録されていて、日記に表示する時に現地
時刻に直しています。このため、天気を記録した時のタイムゾーンと、天気を表
示する時のタイムゾーンが異なってしまうと、例えば朝の天気だったものが夕方
の天気として表示されてしまうことになります。これを防ぐには、例えば、
  @options['weather.tz'] = 'Japan'
というオプションを設定して、データにタイムゾーンを記録するようにしてくだ
さい。tdiary.confなどで、
  ENV['TZ'] = 'Japan'
などとして環境変数TZを設定することでも同様の効果が得られます。環境変数を
設定した場合は、tDiary全体の動作に影響がありますので留意してください。

なお、1.1.2.19かそれ以前のバージョンのweather.rbではタイムゾーンの情報が
天気データに記録されていません。お手数ですが、必要ならば、ファイルを編集
して、タイムゾーン情報を追加してください。記録ファイルは、デフォルトでは、
  .../cache/weather/2003/200301.weather
などにあります。取得元URLの次の数字がUNIX時刻ですので、それに続けて、空
白を一つと、Japanなどタイムゾーンを示す文字列を入力してください。データ
取得時にエラーがなければ、その後2つのタブに続いて、天気のデータが記録さ
れているはずです。

=== オプション
==== 必ず指定が必要な項目
: @options['weather.url']
  天気データを得られるWWWページのURL。
    @options['weather.url'] = 'http://weather.noaa.gov/weather/current/RJTI.html'
  など。情報の二次利用が制限されている場合がありますので、そのようなWWW
  ページから情報を取得しないように注意してください。ブラウザから設定した
  場合はそちらが優先されます。

==== 指定しなくてもいい項目
: @options['weather.show_mobile'] = false
  trueの場合は、携帯端末からのアクセスの場合に、i_html_stringで生成され
  たCHTMLを表示します。falseの場合は、携帯端末からのアクセスの場合には天
  気を表示しません。ブラウザから設定した場合はそちらが優先されます。

: @options['weather.tz']
  データを取得した場所のタイムゾーン。コマンドライン上で例えば、
    TZ=Japan date
  を実行して正しい時刻が表示される文字列を設定してください。Linuxでは、
  /usr/share/zoneinfo以下のファイル名を指定すればいいはずです。ブラウザ
  から設定した場合はそちらが優先されます。このオプションが指定されてい
  ない場合、環境変数TZが設定されていればその値を使用します。そうでなけ
  ればタイムゾーンは記録しません。

  天気データにタイムゾーンが記録されていない場合は、もし将来日記のタイム
  ゾーンが変更された場合に違う時刻を表示することになります。

  日付の判定など、天気データの記録以外の時刻の管理には、日記全体のタイム
  ゾーンが用いられます。

: @options['weather.oldest'] = 21600
  得られたデータが、このオプション(秒)より古い場合には、天気の取得エラー
  になり、次の日記の更新で再びデータを取得しようとします。デフォルトは6
  時間(21600秒)です。このオプションがnilに設定されている場合には、どんな
  に古いデータでも受け入れます。

: @options['weather.show_error']
  データ取得時にエラーがあった場合にそれを日記に表示したい場合にはtrueに
  します。デフォルトでは表示しません。

: @options['weather.dir']
  データの保存場所。デフォルトは以下の通り。
    "#{@cache_path}/weather/"
  この下に、年/年月.weather というファイルが作られます。これを、
  @data_pathと同じにすると、日記のデータと同じディレクトリに天気のデータ
  を保存できるかもしれません。

: @options['weather.items']
  WWWページから取得する項目。デフォルトは、ソースをご覧ください。
  parse_htmlで得られる項目名をキー、記録する項目名を値としたハッシュです。
  www.nws.noaa.govのフォーマットに合わせて、多少の単位の変動には耐えられ
  るようにしてあります。これを変更する場合には、parse_htmlメソッドも編
  集する必要があるかもしれません。

: @options['weather.header']
  HTTPリクエストヘッダに追加する項目のハッシュ
    @options['weather.header'] = {'Accept-language' => 'ja'}
  など。((-Accept-languageによって取得する言語を選べるサイトもあります。-))
  デフォルトでは追加のヘッダは送信しません。

== 天候の翻訳について
NWSからのデータは英語ですので、適当に日本語に直してから出力するようにし
てあります。翻訳は、WeatherTranslatorモジュールによっていて、変換表は、
Weatherクラスに、Words_jaという配列定数として与えてあります。

語彙はまだまだ充分ではないと思います。知らない単語は英語のまま表示されま
すので、Words_jaに適宜追加してください。
((<URL:http://tdiary-users.sourceforge.jp/cgi-bin/wiki.cgi?weather%2Erb>))
に書いておくと、そのうち配布元で追加されるかもしれません。

== 細かい設定
天気データ取得元や好みに合わて、以下のメソッドを変更することで、より柔
軟な設定ができます。

=== 表示に関するもの
: Weather.html_string
  @data[item]を参照して、天気を表示するHTML断片を作ってください。

: Weather.error_html_string
  データ取得エラーがあった場合に、@errorを参照してエラーを表示するHTML断
  片を作ってください。

携帯端末からの閲覧の際には、Weather.i_html_stringが使われます。エラーの
表示はできません。

=== 天気データの取得に関するもの
: Weather.parse_html( html, items )
  ((|html|))文字列を解析して、((|items|))ハッシュに従って@data[item]を定
  義してください。((|items|))には@optins['weather.items']または
  Weather_default_itemsが代入されます。返り値は利用されません。テーブル
  を用いた天気情報源ならば、このメソッドをあまり改造しないで使えるかも
  しれません。

== まだやるべきこと
* 天気に応じたアイコンの表示 -どうやろうか?

== 謝辞
その日の天気プラグインのアイディアを提供してくださったhsbtさん、実装のヒ
ントを提供してくださったzoeさんに感謝します。また、NOAAの情報を提供して
くださったkotakさんに感謝します。

The author appreciates National Weather Service
((<URL:http://weather.noaa.gov/>)) making such valuable data available
in public domain as described in ((<URL:http://www.noaa.gov/wx.html>)).

== Copyright
Copyright 2003 zunda <zunda at freeshell.org>

Permission is granted for use, copying, modification, distribution,
and distribution of modified versions of this work under the terms
of GPL version 2 or later.
=end

=begin
== Instance variables
=end
@weather_plugin_name = 'その日の天気'

=begin
== Classes and methods
=== WeatherTranslator module
We want Japanese displayed in a diary written in Japanese.

--- Weather::Words_ja
    Array of arrays of a Regexp and a Statement to be executed.
    WeatherTranslator::S.tr accepts this kind of hash to translate a
    given string.
=end
require 'erb'

class Weather
	Words_ja = [
		[%r[\A(.*)/(.*)], '"#{S.new( $1 ).translate( table )}/#{S.new( $2 ).translate( table )}"'],
		[%r[\s*\b(greater|more) than (-?[\d.]+\s*\S*)\s*]i, '"#{S.new( $2 ).translate( table )}以上"'],
		[%r[^(.*?) with (.*)$]i, '"#{S.new( $2 ).translate( table )}ありの#{S.new( $1 ).translate( table )}"'],
		[%r[^(.*?) during the past hours?$]i, '"直前まで#{S.new( $1 ).translate( table )}"'],
		#[%r[\s*\b([\w\s]+?) in the vicinity]i, '"近辺で#{S.new( $1).translate( table )}"'],
		[%r[\s*\bin the vicinity\b\s*]i, '""'],
		# ... in the vicinityは無視されるようになっています。訳語が欲しい方は、
		# 上のコメントアウトされている行のコメントを外してください。
		[%r[\s*\bpatches of\b\s*]i, '""'],
		[%r[\s*\bdirection variable\b\s*]i, '"不定"'],
		[%r[\s*(-?[\d.]+)\s*\(?F\)?], '"華氏#{$1}度"'],
		[%r[\s*\bmile(\(?s\)?)?\s*]i, '"マイル"'],
		[%r[\s*\b(mostly |partly )clear\b\s*]i, '"晴"'],
		[%r[\s*\bclear\b\s*]i, '"快晴"'],
		[%r[\s*\b(mostly |partly )?cloudy\b\s*]i, '"曇"'],
		[%r[\s*\bbroken clouds\b\s*]i, '"曇"'],
		[%r[\s*\bfew clouds\b\s*]i, '"晴"'],
		[%r[\s*\bovercast( cloud deck)?\b\s*]i, '"曇"'],
		[%r[\s*\blight snow showers?\b\s*]i, '"にわか雪"'],
		[%r[\s*\blight snow\b\s*]i, '"小雪"'],
		[%r[\s*\blight drizzle\b\s*]i, '"小雨"'],
		[%r[\s*\blight rain showers?\b\s*]i, '"弱いにわか雨"'],
		[%r[\s*\bheavy rain showers?\b\s*]i, '"強いにわか雨"'],
		[%r[\s*\bheavy rain\b\s*]i, '"豪雨"'],
		[%r[\s*\b(rain )?showers?\b\s*]i, '"にわか雨"'],
		[%r[\s*\bdrizzle\b\s*]i, '"こぬか雨"'],
		[%r[\s*\blight rain\b\s*]i, '"霧雨"'],
		[%r[\s*\brain\b\s*]i, '"雨"'],
		[%r[\s*\bmist\b\s*]i, '"靄"'],
		[%r[\s*\bhaze\b\s*]i, '"霞"'],
		[%r[\s*\b(partial )?(freezing )?fog\b\s*]i, '"霧"'],
		[%r[\s*\bsnow\b\s*]i, '"雪"'],
		[%r[\s*\bthunder( storm)?\b\s*]i, '"雷"'],
		[%r[\s*\blightning\b\s*]i, '"稲光"'],
		[%r[\s*\bsand\b\s*]i, '"黄砂"'],
		[%r[\s*\bcumulonimbus clouds\b\s*]i, '"積乱雲"'],
		[%r[\s*\bscattered clouds\b\s*]i, '"ちぎれ雲"'],
		[%r[\s*\bcumulus clouds\b\s*]i, '"積雲"'],
		[%r[\Aunknown\z]i, '""'],
		[%r[\s*\btowering\b\s*]i, '""'],
		[%r[\s*\bobserved\b\s*]i, '""'],
		[%r[\s*\bC\b\s*], '"℃"'],
	].freeze
end

=begin
=== Weather class
Weather of a date.
--- Weather.html_string
--- Weather.error_html_string
      Returns an HTML fragment showing data or error, called from
      Weather.to_html.

--- Weather.i_html_string
      Returns a CHTML fragment to be shown on a mobile browser.
=end
class Weather
	include ERB::Util

	def error_html_string
		%Q|<span class="weather">お天気エラー:<a href="#{h(@url)}">#{h( @error )}</a></span>|
	end

	# edit this method to define how you show the weather
	def html_string
		has_data = false
		r = '<span class="weather">'

		# time stamp
		if @tz then
			tzbak = ENV['TZ']
			ENV['TZ'] = @tz	# this is not thread safe...
		end
		if @data['timestamp'] then
			r << Time::at( @data['timestamp'].to_i ).strftime( '%H:%M' ).sub( /^0/, '' )
		else
			r << Time::at( @time.to_i ).strftime( '%H:%M' ).sub( /^0/, '' )
		end
		r << '現在'
		if @tz then
			ENV['TZ'] = tzbak
		end

		# weather
		r << %Q|<a href="#{h(@url)}">|
		if @data['weather'] then
			r << %Q|<span class="weather">#{h( WeatherTranslator::S.new( @data['weather']).translate( Words_ja ).compact )}</span>|
			has_data = true
		elsif @data['condition'] then
			r << %Q|<span class="condition">#{h( WeatherTranslator::S.new( @data['condition']).translate( Words_ja ).compact )}</span>|
			has_data = true
		end

		# temperature
		if @data['temperature(C)'] and t = @data['temperature(C)'].scan(/-?[\d.]+/)[-1] then
			r << %Q| <span class="temperature">#{sprintf( '%.0f', t )}℃</span>|
			has_data = true
		end

		r << "</a></span>"
		return has_data ? r : ''
	end

	# edit this method to define how you show the weather for a mobile agent
	def i_html_string
		r = ''

		# weather
		if @data['weather'] then
			r << %Q|<A HREF="#{u(@url)}">|
			r << h( WeatherTranslator::S.new( @data['weather']).translate( Words_ja ).compact )
			r << "</A>"
		elsif @data['condition'] then
			r << %Q|<A HREF="#{u(@url)}">|
			r << h( WeatherTranslator::S.new( @data['condition']).translate( Words_ja ).compact )
			r << "</A>"
		end

		return r
	end
end

# www configuration interface
def weather_configure_html( conf )
	station = Weather::extract_station_id(conf['weather.url'])
	station ||= conf['weather.url']
	<<-HTML
	<h3 class="subtitle">その日の天気プラグイン</h3>
	<p>その日の天気を、その日の日記を最初に更新する時に取得して保存し、
		それぞれの日の日記の上部に表示します。</p>
	<h4>天気データ</h4>
	<p>その日の天気を、例えばNOAA National Weather Serviceを利用する場合には、
		<a href="http://weather.noaa.gov/">NOAA National Weather Service</a>
		から、Select a country...で国名を選んでGo!ボタンを押し、
		次に観測地点を選んでください。
		そして、その時表示されたページのURL
		(例えば東京ヘリポートの場合は<tt>http://weather.noaa.gov/weather/current/RJTI.html</tt>となります)
		を、以下に記入してください。
		大文字4文字のStation IDでもかまいません。</p>
	<p><input name="weather.url" value="#{station}" size="50"></p>
	<p>将来日記のタイムゾーンが変化する可能性がある方は、
		今のタイムゾーンを記録しておくことをお勧めします。
		これによって、日記が引越した後も、
		天気データ取得時のタイムゾーンで天気を表示し続けることができます。</p>
	<p>タイムゾーンを記録するには、例えば日本標準時の場合には、
		tdiary.rbと同じディレクトリにあるtdiary.confに、
		ENV['TZ'] = 'Japan'などと書き足すか、
		以下に、Japanと記入してください。</p>
	<p><input name="weather.tz" value="#{conf['weather.tz']}"></p>
	<h4>WWWブラウザへの表示</h4>
	<p>下記から選んでください。</p>
	<p><select name="weather.in_title">
		<option value="false"#{' selected'unless conf['weather.in_title']}>
		本文の上に表示する
		<option value="true"#{' selected'if conf['weather.in_title']}>
		タイトルの横に表示する
	</select></p>
	<h4>携帯電話への表示</h4>
	<p>下記から選んでください。</p>
	<p><select name="weather.show_mobile">
		<option value="true"#{' selected'if conf['weather.show_mobile']}>
		携帯電話にも今日の天気を表示する
		<option value="false"#{' selected'unless conf['weather.show_mobile']}>
		携帯電話には今日の天気を表示しない
	</select></p>
	<h4>検索エンジンなどのロボットへの表示</h4>
	<p>下記から選んでください。</p>
	<p><select name="weather.show_robot">
		<option value="true"#{' selected'if conf['weather.show_robot']}>
		検索エンジンなどのロボットにも今日の天気を知らせる
		<option value="false"#{' selected'unless conf['weather.show_robot']}>
		検索エンジンなどのロボットには今日の天気を知らせない
	</select></p>
	<h4>その他の設定</h4>
	<p>この他にもいくつかtdiary.confから設定できる項目があります。
		詳しくは、プラグインのファイル(weather.rb)をご覧ください。</p>
	HTML
end


# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End: