tdiary 4.0.2.20140201 → 4.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/ChangeLog +3 -0
- data/Gemfile +5 -5
- data/Gemfile.lock +48 -29
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/index.rb +2 -2
- data/js/01conf.js +16 -0
- data/misc/convert2.rb +3 -3
- data/misc/filter/limitdays.rb +2 -2
- data/misc/filter/linkcheck.rb +2 -2
- data/misc/lib/fcgi_patch.rb +3 -3
- data/misc/paas/cloudfoundry/Gemfile.lock +51 -48
- data/misc/paas/heroku/Gemfile.lock +23 -21
- data/misc/paas/sqale/Gemfile.lock +23 -21
- data/misc/plugin/a.rb +4 -4
- data/misc/plugin/calendar2.rb +1 -1
- data/misc/plugin/category.rb +3 -3
- data/misc/plugin/comment_emoji_autocomplete.rb +1 -1
- data/misc/plugin/comment_mail-qmail.rb +1 -1
- data/misc/plugin/comment_mail-sendmail.rb +1 -1
- data/misc/plugin/comment_mail-smtp.rb +1 -1
- data/misc/plugin/counter.rb +27 -27
- data/misc/plugin/disp_referrer.rb +1 -1
- data/misc/plugin/en/amazon.rb +2 -2
- data/misc/plugin/en/category.rb +1 -1
- data/misc/plugin/en/counter.rb +1 -1
- data/misc/plugin/en/disp_referrer.rb +1 -1
- data/misc/plugin/en/kw.rb +1 -1
- data/misc/plugin/en/search_form.rb +1 -1
- data/misc/plugin/en/todo.rb +1 -1
- data/misc/plugin/en/weather.rb +5 -2
- data/misc/plugin/image.rb +2 -2
- data/misc/plugin/ja/disp_referrer.rb +7 -7
- data/misc/plugin/ja/my-sequel.rb +1 -1
- data/misc/plugin/ja/recent_comment3.rb +1 -1
- data/misc/plugin/ja/referer_scheme.rb +1 -1
- data/misc/plugin/ja/search_control.rb +1 -1
- data/misc/plugin/ja/search_form.rb +2 -2
- data/misc/plugin/ja/todo.rb +1 -1
- data/misc/plugin/ja/weather.rb +17 -12
- data/misc/plugin/makelirs.rb +4 -4
- data/misc/plugin/my-ex.rb +1 -1
- data/misc/plugin/my-sequel.rb +1 -1
- data/misc/plugin/pb-show.rb +1 -1
- data/misc/plugin/recent_comment.rb +5 -5
- data/misc/plugin/recent_comment3.rb +2 -2
- data/misc/plugin/recent_namazu.rb +4 -4
- data/misc/plugin/recent_rss.rb +7 -7
- data/misc/plugin/referer_scheme.rb +2 -2
- data/misc/plugin/search-default.rb +1 -1
- data/misc/plugin/sn.rb +3 -3
- data/misc/plugin/speed_comment.rb +1 -1
- data/misc/plugin/squeeze.rb +8 -8
- data/misc/plugin/tb-show.rb +1 -1
- data/misc/plugin/theme_online.rb +25 -0
- data/misc/plugin/tlink.rb +2 -2
- data/misc/plugin/todo.rb +2 -2
- data/misc/plugin/weather.rb +82 -26
- data/misc/plugin/whatsnew.rb +1 -1
- data/misc/plugin/xmlrpc/xmlrpc.rb +11 -11
- data/misc/theme_convert/theme_convert.rb +3 -3
- data/plugin/00default.rb +35 -28
- data/plugin/50sp.rb +1 -1
- data/plugin/60sf.rb +1 -1
- data/plugin/90migrate.rb +2 -2
- data/plugin/en/00default.rb +1 -1
- data/plugin/ja/00default.rb +1 -1
- data/spec/acceptance/append_comment_spec.rb +18 -18
- data/spec/acceptance/append_diary_spec.rb +22 -22
- data/spec/acceptance/bugfix/encoding_error_spec.rb +1 -1
- data/spec/acceptance/save_conf_comment_spec.rb +15 -15
- data/spec/acceptance/save_conf_default_spec.rb +26 -26
- data/spec/acceptance/save_conf_dnsbl_spec.rb +19 -19
- data/spec/acceptance/save_conf_filter_spec.rb +6 -6
- data/spec/acceptance/save_conf_plugin_spec.rb +11 -11
- data/spec/acceptance/save_conf_referer_spec.rb +4 -4
- data/spec/acceptance/save_conf_security_spec.rb +28 -28
- data/spec/acceptance/update_diary_spec.rb +16 -16
- data/spec/acceptance/view_category_spec.rb +1 -1
- data/spec/acceptance/view_comment_spec.rb +6 -6
- data/spec/acceptance/view_diary_spec.rb +25 -25
- data/spec/acceptance/view_referer_spec.rb +3 -3
- data/spec/core/compatible_spec.rb +5 -5
- data/spec/core/configuration_spec.rb +3 -3
- data/spec/core/core_ext_spec.rb +7 -7
- data/spec/core/io/default_spec.rb +1 -1
- data/spec/core/plugin_spec.rb +41 -41
- data/spec/core/rack/assets/precompile_spec.rb +3 -3
- data/spec/core/rack/html_anchor_spec.rb +15 -15
- data/spec/core/rack/static_spec.rb +3 -3
- data/spec/core/rack/valid_request_path_spec.rb +13 -13
- data/spec/core/style/tdiary_style_spec.rb +10 -10
- data/spec/core/style/wiki_style_spec.rb +16 -16
- data/spec/plugin/bq_spec.rb +2 -2
- data/spec/spec_helper.rb +3 -1
- data/tdiary/configuration.rb +2 -2
- data/tdiary/environment.rb +1 -1
- data/tdiary/io/default.rb +1 -1
- data/tdiary/lang/ja.rb +2 -2
- data/tdiary/tasks/db.rake +5 -5
- data/tdiary/version.rb +1 -1
- data/test/disp_referrer_test.rb +4 -4
- data/test/my-sequel_test.rb +1 -1
- data/test/test_plugin_helper.rb +47 -0
- data/test/weather-ADDS-METARS-PHTO-140131.html +109 -0
- data/test/weather-ADDS-METARS-RJAA-130131.html +111 -0
- data/test/weather-ADDS-METARS-RJAA-130227.html +111 -0
- data/test/weather_test.rb +144 -18
- data/update.rb +2 -2
- metadata +10 -3
data/misc/plugin/pb-show.rb
CHANGED
@@ -22,7 +22,7 @@ def recent_comment( ob_max = 'OBSOLUTE', sep = 'OBSOLUTE', ob_form = 'OBSOLUTE',
|
|
22
22
|
recent_comment_init
|
23
23
|
|
24
24
|
max = @conf['recent_comment.max']
|
25
|
-
form = @conf['recent_comment.date_format']
|
25
|
+
form = @conf['recent_comment.date_format']
|
26
26
|
except = @conf['recent_comment.except_list']
|
27
27
|
format = @conf['recent_comment.format']
|
28
28
|
notfound_msg = @conf['recent_comment.notfound_msg']
|
@@ -34,7 +34,7 @@ def recent_comment( ob_max = 'OBSOLUTE', sep = 'OBSOLUTE', ob_form = 'OBSOLUTE',
|
|
34
34
|
@diaries.each_value do |diary|
|
35
35
|
next unless diary.visible?
|
36
36
|
diary.each_comment_tail( max ) do |comment, idx|
|
37
|
-
if (except != '') && (/#{except}/ =~ comment.name)
|
37
|
+
if (except != '') && (/#{except}/ =~ comment.name)
|
38
38
|
next
|
39
39
|
end
|
40
40
|
comments << comment
|
@@ -42,9 +42,9 @@ def recent_comment( ob_max = 'OBSOLUTE', sep = 'OBSOLUTE', ob_form = 'OBSOLUTE',
|
|
42
42
|
index[comment.date] = idx
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
result = []
|
47
|
-
|
47
|
+
|
48
48
|
comments.sort{|a,b| (a.date)<=>(b.date)}.reverse.each_with_index do |com,idx|
|
49
49
|
break if idx >= max
|
50
50
|
a = h(@index) + anchor("#{date[com.date].strftime( '%Y%m%d' )}#c#{'%02d' % index[com.date]}")
|
@@ -56,7 +56,7 @@ def recent_comment( ob_max = 'OBSOLUTE', sep = 'OBSOLUTE', ob_form = 'OBSOLUTE',
|
|
56
56
|
result << recent_comment_format(format, idx, a, popup, str, date_str)
|
57
57
|
result << "</li>\n"
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
if result.size == 0
|
61
61
|
notfound_msg
|
62
62
|
else
|
@@ -18,7 +18,7 @@ end
|
|
18
18
|
|
19
19
|
def migrate_old_data
|
20
20
|
# backward compatibility
|
21
|
-
if File.
|
21
|
+
if File.exist?("#{@cache_path}/recent_comments") && !File.exist?("{#{@conf.data_path}/recent_comments")
|
22
22
|
FileUtils.mv( "#{@cache_path}/recent_comments", "#{@conf.data_path}/recent_comments" )
|
23
23
|
end
|
24
24
|
# workaround for "/foo//bar" doesn't equal "/foo/bar"
|
@@ -47,7 +47,7 @@ def recent_comment3(ob_max = 'OBSOLUTE' ,sep = 'OBSOLUTE',ob_date_format = 'OBSO
|
|
47
47
|
recent_comment3_init
|
48
48
|
|
49
49
|
cache = @conf['recent_comment3.cache'].untaint
|
50
|
-
date_format = @conf['recent_comment3.date_format']
|
50
|
+
date_format = @conf['recent_comment3.date_format']
|
51
51
|
excepts = @conf['recent_comment3.except_list'].split(/,/)
|
52
52
|
format = @conf['recent_comment3.format']
|
53
53
|
titlelen = @conf['recent_comment3.titlelen']
|
@@ -5,11 +5,11 @@
|
|
5
5
|
# namazi.cgiが作成する検索キーワードログ(NMZ.slog)から
|
6
6
|
# 最新xx件分の検索語を表示します。
|
7
7
|
# パラメタ:
|
8
|
-
# file: 検索キーワードログファイル名(絶対パス表記)
|
9
|
-
# namazu: なまずcgi名
|
10
|
-
# limit: 表示件数(未指定時:5)
|
8
|
+
# file: 検索キーワードログファイル名(絶対パス表記)
|
9
|
+
# namazu: なまずcgi名
|
10
|
+
# limit: 表示件数(未指定時:5)
|
11
11
|
# sep: セパレータ(未指定時:空白)
|
12
|
-
# make_link: <a>を生成するか?(未指定時:生成する)
|
12
|
+
# make_link: <a>を生成するか?(未指定時:生成する)
|
13
13
|
#
|
14
14
|
#
|
15
15
|
# Copyright (c) 2002 Hiroyuki Ikezoe <zoe@kasumi.sakura.ne.jp>
|
data/misc/plugin/recent_rss.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- indent-tabs-mode: t -*-
|
2
|
-
# recent_rss.rb: RSS recent plugin
|
2
|
+
# recent_rss.rb: RSS recent plugin
|
3
3
|
#
|
4
4
|
# options:
|
5
5
|
# @options['recent_rss.use-image-link'] : use image as link
|
@@ -35,13 +35,13 @@ def recent_rss( url, max = 5, cache_time = 3600, show_modified = true )
|
|
35
35
|
cache_file = "#{@cache_path}/recent_rss.#{CGI.escape(url)}"
|
36
36
|
|
37
37
|
recent_rss_cache_rss(url, cache_file, cache_time.to_i)
|
38
|
-
|
38
|
+
|
39
39
|
return '' unless test(?r, cache_file)
|
40
40
|
|
41
41
|
rv = %Q|<div class="recent-rss">\n|
|
42
42
|
|
43
43
|
site_info, *infos = recent_rss_read_from_cache(cache_file)
|
44
|
-
|
44
|
+
|
45
45
|
if site_info
|
46
46
|
title, url, time, image = site_info
|
47
47
|
content = recent_rss_entry_to_html( title, url, time, image, show_modified )
|
@@ -49,9 +49,9 @@ def recent_rss( url, max = 5, cache_time = 3600, show_modified = true )
|
|
49
49
|
rv << %Q|<span class="#{recent_rss_modified_class(time)}">#{content}</span>\n|
|
50
50
|
rv << "</div>\n"
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
have_entry = infos.size > 0 && max > 0
|
54
|
-
|
54
|
+
|
55
55
|
rv << %Q|<ol class="recent-rss">\n| if have_entry
|
56
56
|
i = 0
|
57
57
|
infos.each do |title, url, time, image|
|
@@ -93,14 +93,14 @@ def recent_rss_cache_rss(url, cache_file, cache_time)
|
|
93
93
|
cached_time = File.mtime(cache_file) if File.exist?(cache_file)
|
94
94
|
|
95
95
|
if cached_time.nil? or Time.now > cached_time + cache_time
|
96
|
-
|
96
|
+
|
97
97
|
begin
|
98
98
|
uri = URI.parse(url)
|
99
99
|
|
100
100
|
raise URI::InvalidURIError unless uri.is_a?(URI::HTTP)
|
101
101
|
|
102
102
|
rss_source = recent_rss_fetch_rss(uri, cached_time)
|
103
|
-
|
103
|
+
|
104
104
|
raise InvalidResourceError if rss_source.nil?
|
105
105
|
|
106
106
|
# parse RSS
|
@@ -30,12 +30,12 @@ end
|
|
30
30
|
|
31
31
|
unless @conf.referer_table.respond_to?( 'scheme_tdiary', true ) then
|
32
32
|
class << @conf.referer_table
|
33
|
-
TdiaryDates = [
|
33
|
+
TdiaryDates = [
|
34
34
|
['(?:\\?date=)?(\d{4})(\d{2})(\d{2})-(\d+)(?:\.html)?.*', '(\1-\2-\3~)'],
|
35
35
|
['(?:\\?date=)?(\d{4})(\d{2})(\d{2})(?:\.html)?.*', '(\1-\2-\3)'],
|
36
36
|
['(?:\\?date=)?(\d{4})(\d{2})(?:\.html)?.*', '(\1-\2)'],
|
37
37
|
['(?:\\?date=)?(\d{2})(\d{2})(?:\.html)?.*', '(\1-\2)'],
|
38
|
-
]
|
38
|
+
]
|
39
39
|
private
|
40
40
|
def scheme_tdiary( url, name )
|
41
41
|
TdiaryDates.each do |a|
|
@@ -233,7 +233,7 @@ end
|
|
233
233
|
|
234
234
|
def search_result
|
235
235
|
unless @conf.io_class == (TDiary.const_defined?('DefaultIO') ? TDiary::DefaultIO : TDiary::IO::Default)
|
236
|
-
return %Q|<p class="message">could not use this plugin under #{@conf.io_class}.</p>|
|
236
|
+
return %Q|<p class="message">could not use this plugin under #{@conf.io_class}.</p>|
|
237
237
|
end
|
238
238
|
|
239
239
|
query = CGI::unescape( @cgi.params['q'][0] )
|
data/misc/plugin/sn.rb
CHANGED
@@ -62,13 +62,13 @@
|
|
62
62
|
* first version
|
63
63
|
=end
|
64
64
|
|
65
|
-
add_body_enter_proc do |date|
|
65
|
+
add_body_enter_proc do |date|
|
66
66
|
@sn_count = 1
|
67
67
|
@sn_idx = 0
|
68
68
|
""
|
69
69
|
end
|
70
70
|
|
71
|
-
add_body_leave_proc do |date|
|
71
|
+
add_body_leave_proc do |date|
|
72
72
|
@sn_count = 1
|
73
73
|
@sn_idx = 0
|
74
74
|
""
|
@@ -94,7 +94,7 @@ def sn( number = nil )
|
|
94
94
|
@sn_count += 1
|
95
95
|
%Q[#{'%d' % number}]
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
def sn_anchorid
|
99
99
|
%Q[#{'%d' % @sn_idx}]
|
100
100
|
end
|
data/misc/plugin/squeeze.rb
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
# Create daily HTML file from tDiary database.
|
6
6
|
#
|
7
7
|
# See URLs below for more details.
|
8
|
-
# http://ponx.s5.xrea.com/hiki/squeeze.rb.html (English)
|
9
|
-
# http://ponx.s5.xrea.com/hiki/ja/squeeze.rb.html (Japanese)
|
8
|
+
# http://ponx.s5.xrea.com/hiki/squeeze.rb.html (English)
|
9
|
+
# http://ponx.s5.xrea.com/hiki/ja/squeeze.rb.html (Japanese)
|
10
10
|
#
|
11
11
|
# Copyright (C) 2002 MUTOH Masao <mutoh@highway.ne.jp>
|
12
12
|
# You can redistribute it and/or modify it under GPL2.
|
13
13
|
#
|
14
|
-
# The original version of this file was distributed with squeeze
|
14
|
+
# The original version of this file was distributed with squeeze
|
15
15
|
# TADA Tadashi <sho@spc.gr.jp> with GPL2.
|
16
16
|
#
|
17
17
|
unless $tdiary_squeeze_loaded
|
@@ -77,7 +77,7 @@ if mode == "CMD" || mode == "CGI"
|
|
77
77
|
$:.unshift tdiary_path
|
78
78
|
else
|
79
79
|
@options = Hash.new
|
80
|
-
File::readlines("tdiary.conf").each {|item|
|
80
|
+
File::readlines("tdiary.conf").each {|item|
|
81
81
|
if item =~ /@options/
|
82
82
|
begin
|
83
83
|
eval(item)
|
@@ -114,7 +114,7 @@ module ::TDiary
|
|
114
114
|
class YATDiarySqueeze < TDiaryBase
|
115
115
|
def initialize(diary, dest, all_data, overwrite, compat, conf, suffix)
|
116
116
|
@ignore_parser_cache = true
|
117
|
-
|
117
|
+
|
118
118
|
cgi = CGI::new
|
119
119
|
def cgi.referer; nil; end
|
120
120
|
def cgi.user_agent; 'bot'; end
|
@@ -128,7 +128,7 @@ module ::TDiary
|
|
128
128
|
@compat = compat
|
129
129
|
@suffix = suffix
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
def execute
|
133
133
|
if @compat
|
134
134
|
dir = @dest
|
@@ -143,7 +143,7 @@ module ::TDiary
|
|
143
143
|
File::delete( filename )
|
144
144
|
end
|
145
145
|
if @diary.visible? or @all_data
|
146
|
-
if not FileTest::exist?(filename) or
|
146
|
+
if not FileTest::exist?(filename) or
|
147
147
|
File::mtime(filename) != @diary.last_modified
|
148
148
|
File::open(filename, 'w'){|f| f.write(eval_rhtml)}
|
149
149
|
File::utime(@diary.last_modified, @diary.last_modified, filename)
|
@@ -158,7 +158,7 @@ module ::TDiary
|
|
158
158
|
end
|
159
159
|
name
|
160
160
|
end
|
161
|
-
|
161
|
+
|
162
162
|
protected
|
163
163
|
def mode
|
164
164
|
'day'
|
data/misc/plugin/tb-show.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
# theme_online.rb: choice theme from online repository on tDiary.org
|
2
|
+
#
|
3
|
+
# Copyright (C) 2014 by TADA Tadashi <t@tdtds.jp>
|
4
|
+
# You can distribute and/or modify it under GPL
|
5
|
+
#
|
6
|
+
require 'json'
|
7
|
+
require 'open-uri'
|
8
|
+
|
9
|
+
def theme_list_online(list)
|
10
|
+
begin
|
11
|
+
online_list = JSON.load(open('http://theme.tdiary.org/themes.json', &:read))['themes']
|
12
|
+
list + online_list.keys.map do |t|
|
13
|
+
title = online_list[t]['title']
|
14
|
+
label = t == title ? '' : " (#{title})"
|
15
|
+
["online/#{t}", "#{t}#{label}"]
|
16
|
+
end
|
17
|
+
rescue
|
18
|
+
@logger.error "could not get theme list from online: #$!"
|
19
|
+
list
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def theme_url_online(theme)
|
24
|
+
"http://theme.tdiary.org/#{h theme}/#{h theme}.css"
|
25
|
+
end
|
data/misc/plugin/tlink.rb
CHANGED
@@ -41,7 +41,7 @@
|
|
41
41
|
|
42
42
|
2002-05-16 MUTOH Masao <mutoh@highway.ne.jp>
|
43
43
|
* cache mechanism support.
|
44
|
-
* code cleanup(remove require 'cgi',
|
44
|
+
* code cleanup(remove require 'cgi',
|
45
45
|
getcomment rename to tlink_getcomment).
|
46
46
|
|
47
47
|
2002-05-05 NT <nt@24i.net>
|
@@ -70,7 +70,7 @@ require 'net/http'
|
|
70
70
|
require 'kconv'
|
71
71
|
require 'pstore'
|
72
72
|
|
73
|
-
def tlink_initialize
|
73
|
+
def tlink_initialize
|
74
74
|
dir = @cache_path + "/tlink"
|
75
75
|
@tlink_path = dir + "/tlink.dat"
|
76
76
|
|
data/misc/plugin/todo.rb
CHANGED
@@ -34,7 +34,7 @@
|
|
34
34
|
#
|
35
35
|
# Copyright (c) 2001,2002,2003 Junichiro KITA <kita@kitaj.no-ip.com>
|
36
36
|
# Distributed under the GPL
|
37
|
-
#
|
37
|
+
#
|
38
38
|
|
39
39
|
require 'fileutils'
|
40
40
|
require 'time'
|
@@ -146,7 +146,7 @@ end
|
|
146
146
|
|
147
147
|
# backward compatibility
|
148
148
|
def todo_file
|
149
|
-
if File.
|
149
|
+
if File.exist?( "#{@cache_path}/todo" ) then
|
150
150
|
FileUtils.mv( "#{@cache_path}/todo", "#{@conf.data_path}/todo")
|
151
151
|
end
|
152
152
|
(@options && @options['todo.path'] || @conf.data_path) + "/todo"
|
data/misc/plugin/weather.rb
CHANGED
@@ -68,9 +68,17 @@ of GPL version 2 or later.
|
|
68
68
|
require 'net/http'
|
69
69
|
require 'cgi'
|
70
70
|
require 'timeout'
|
71
|
+
require 'date' # DateTime.strptime
|
71
72
|
|
72
73
|
=begin
|
73
74
|
== Classes and methods
|
75
|
+
=== WeatherParser
|
76
|
+
|
77
|
+
--- WeatherParser::parse
|
78
|
+
=end
|
79
|
+
|
80
|
+
|
81
|
+
=begin
|
74
82
|
=== WeatherTranslator module
|
75
83
|
We want Japanese displayed in a diary written in Japanese.
|
76
84
|
|
@@ -144,45 +152,61 @@ class Weather
|
|
144
152
|
# magic numbers
|
145
153
|
WAITTIME = 10
|
146
154
|
MAXREDIRECT = 10
|
155
|
+
AVIATIONWEATHER_STATION_REGEXP = %r|(?:aviationweather.gov/adds/metars/\?.*station_ids=)([A-Z]{4,4})\b|
|
156
|
+
NOAA_STATION_REGEXP = %r|(?:weather.noaa.gov/weather/current/)([A-Z]{4,4})\b|
|
157
|
+
RAW_STATION_REGEXP = %r|\A([A-Z]{4,4})\z|
|
158
|
+
STATION_URL_TEMPLATE = "http://www.aviationweather.gov/adds/metars/?station_ids=%s&std_trans=translated&chk_metars=on&hoursStr=most+recent+only"
|
159
|
+
|
160
|
+
def Weather::extract_station_id(url)
|
161
|
+
[AVIATIONWEATHER_STATION_REGEXP, NOAA_STATION_REGEXP, RAW_STATION_REGEXP].each do |r|
|
162
|
+
m = r.match(url)
|
163
|
+
return m[1] if m and m[1]
|
164
|
+
end
|
165
|
+
return nil
|
166
|
+
end
|
147
167
|
|
148
168
|
# edit this method according to the HTML we will get
|
149
169
|
def parse_html( html, items )
|
150
170
|
htmlitems = Hash.new
|
151
171
|
|
152
|
-
# weather data is in the
|
153
|
-
table = html.scan( %r[<table.*?>(.*?)</table>]mi )
|
154
|
-
table
|
172
|
+
# weather data is in the 1st table in the HTML from aviationweather.gov
|
173
|
+
table = html.scan( %r[<table.*?>(.*?)</table>]mi )
|
174
|
+
return if not table or not table[0] or not table[0][0]
|
175
|
+
table[0][0].scan( %r[<tr.*?>(.*?)</tr>]mi ).collect {|a| a[0]}.each do |row|
|
155
176
|
# <tr><td> *item* -> downcased </td><td> *value* </td></tr>
|
156
177
|
if %r[<td.*?>(.*?)</td>\s*<td.*?>(.*?)</td>]mi =~ row then
|
157
178
|
item = $1
|
158
179
|
value = $2
|
159
|
-
item = item.gsub( /<br>/i, '/' ).gsub( /<.*?>/m , '').strip.downcase
|
160
|
-
value = value.gsub( /<br>/i, '/' ).gsub( /<.*?>/m , '').strip
|
180
|
+
item = item.gsub( /<br>/i, '/' ).gsub( /<.*?>/m , '').strip.sub(/:$/, '').downcase
|
181
|
+
value = value.gsub(/\&(nbsp|#160);/, ' ').gsub(/\./, '.').gsub(/\%/, '%').gsub(/\°/, '').gsub( /<br>/i, '/' ).gsub( /<.*?>/m , '').strip
|
161
182
|
|
162
183
|
# unit conversion settings
|
163
184
|
units = []
|
164
185
|
case item
|
165
186
|
when 'conditions at'
|
166
187
|
# we have to convert the UTC time into UNIX time
|
167
|
-
if /
|
168
|
-
value =
|
188
|
+
if /observed\s+(.*)$/ =~ value then
|
189
|
+
value = DateTime.strptime($1, "%H%M %z %d %B %Y").to_time.to_i.to_s
|
169
190
|
else
|
170
191
|
raise StandardError, 'Parse error in "Conditions at"'
|
171
192
|
end
|
172
193
|
when 'visibility' # we want to preserve adjective phrase if possible
|
173
|
-
if /(
|
174
|
-
htmlitems["#{item}(
|
175
|
-
|
194
|
+
if /(.+)miles?/i =~ value then
|
195
|
+
htmlitems["#{item}(mile)"] = $1.strip
|
196
|
+
end
|
197
|
+
if /([^\(]+)km/i =~ value then
|
198
|
+
htmlitems["#{item}(km)"] = $1.strip
|
199
|
+
end
|
200
|
+
when 'winds' # we want to preserve adjective phrase if possible
|
201
|
+
%w(MPH knots m/s).each do |unit|
|
202
|
+
speed = value.scan( /([\d.]+)\s*#{unit}/i ).collect { |x| x[0] }
|
203
|
+
htmlitems["wind(#{unit})"] = speed.join(',')
|
176
204
|
end
|
177
|
-
when 'wind' # we want to preserve adjective phrase if possible
|
178
|
-
speed = value.scan( /([\d.]+)\s*MPH/i ).collect { |x| x[0] }
|
179
|
-
htmlitems["#{item}(MPH)"] = speed.join(',')
|
180
|
-
htmlitems["#{item}(m/s)"] = speed.collect {|s| sprintf( '%.4f', s.to_f * 0.4472222 ) }.join(',')
|
181
205
|
if /([\d.]+)\s*degrees?/i =~ value then
|
182
|
-
htmlitems["
|
206
|
+
htmlitems["wind(deg)"] = $1
|
183
207
|
end
|
184
208
|
if /from\s+(the\s+)?(\w+)/i =~ value then
|
185
|
-
htmlitems["
|
209
|
+
htmlitems["winddir"] = $2 + ($3 ? " #{$3}" : '')
|
186
210
|
end
|
187
211
|
if /(\(direction variable\))/i =~ value then
|
188
212
|
htmlitems["#{item}dir"] << " #{$1}"
|
@@ -192,18 +216,19 @@ class Weather
|
|
192
216
|
units = ['C', 'F']
|
193
217
|
when 'windchill'
|
194
218
|
units = ['C', 'F']
|
195
|
-
when '
|
219
|
+
when 'dewpoint'
|
196
220
|
units = ['C', 'F']
|
197
221
|
when 'relative humidity'
|
198
222
|
units = ['%']
|
199
223
|
when 'pressure (altimeter)'
|
200
|
-
units = ['
|
224
|
+
units = ['mb'] # mb (mbar) and hPa results in same number
|
201
225
|
end
|
202
226
|
|
203
227
|
# parse the value with the units if preferred and possible
|
204
228
|
units.each do |unit|
|
205
|
-
if /(-?[\d.]+)\s*\(?#{unit}\b/i =~ value then
|
206
|
-
|
229
|
+
if /(-?[\d.]+)\s*\D?\(?#{unit}\b/i =~ value then
|
230
|
+
number = $1
|
231
|
+
htmlitems["#{item}(#{unit})"] = number
|
207
232
|
end
|
208
233
|
end
|
209
234
|
|
@@ -213,6 +238,18 @@ class Weather
|
|
213
238
|
end # if %r[<td.*?>(.*?)</td>\s*<td.*?>(.*?)</td>]mi =~ row
|
214
239
|
end # table.scan( %r[<tr.*?>(.*?)</tr>]mi ) ... do |row|
|
215
240
|
|
241
|
+
# Obtain weather from Weather: or Clouds:
|
242
|
+
weather = 'Unknown'
|
243
|
+
# e.g.: FG -RA (fog, light rain)
|
244
|
+
if /\((.*)\)/ =~ htmlitems['weather'] then
|
245
|
+
weather = $1.strip
|
246
|
+
# e.g.: few clouds at 3000 feet AGL
|
247
|
+
elsif /(.*?)\s+at/ =~ htmlitems['clouds'] then
|
248
|
+
weather = $1.strip
|
249
|
+
end
|
250
|
+
# Weather seemed to have been slash divided capitalized string
|
251
|
+
htmlitems['weather'] = weather.split(/,\s*/).map{|e| e.strip.capitalize}.join('/')
|
252
|
+
|
216
253
|
# translate the parsed HTML into the Weather hash with more generic key
|
217
254
|
items.each do |from, to|
|
218
255
|
if htmlitems[from] then
|
@@ -257,7 +294,7 @@ class Weather
|
|
257
294
|
px_port = 80 if px_host and !px_port
|
258
295
|
u = URI::parse( url )
|
259
296
|
Net::HTTP::Proxy( px_host, px_port ).start( u.host, u.port ) do |http|
|
260
|
-
case res = http.get( u.
|
297
|
+
case res = http.get( u.request_uri, header )
|
261
298
|
when Net::HTTPSuccess
|
262
299
|
res.body
|
263
300
|
when Net::HTTPRedirection
|
@@ -406,9 +443,9 @@ Weather_default_items = {
|
|
406
443
|
'visibility(km)' => 'visibility(km)',
|
407
444
|
'temperature(C)' => 'temperature(C)',
|
408
445
|
'windchill(C)' => 'windchill(C)',
|
409
|
-
'
|
446
|
+
'dewpoint(C)' => 'dewpoint(C)',
|
410
447
|
'relative humidity(%)' => 'humidity(%)',
|
411
|
-
'pressure (altimeter)(
|
448
|
+
'pressure (altimeter)(mb)' => 'pressure(hPa)',
|
412
449
|
}
|
413
450
|
|
414
451
|
# shows weather
|
@@ -436,6 +473,7 @@ def get_weather
|
|
436
473
|
w = Weather::restore( path, @date )
|
437
474
|
if not w or w.error then
|
438
475
|
items = @options['weather.items'] || Weather_default_items
|
476
|
+
update_weather_url( @options )
|
439
477
|
w = Weather.new( @date, @options['weather.tz'], @conf )
|
440
478
|
w.get( @options['weather.url'], @options['weather.header'] || {}, items )
|
441
479
|
if @options.has_key?( 'weather.oldest' ) then
|
@@ -448,11 +486,28 @@ def get_weather
|
|
448
486
|
end
|
449
487
|
end
|
450
488
|
|
489
|
+
# Update URL of weather information
|
490
|
+
#
|
491
|
+
# Around April, 2012, NOAA chnaged the URL of the current weather from
|
492
|
+
# http://weather.noaa.gov/weather/current/#{station_id}.html
|
493
|
+
# to
|
494
|
+
# http://www.aviationweather.gov/adds/metars/?station_ids=#{station_id}&std_trans=translated&chk_metars=on&hoursStr=most+recent+only
|
495
|
+
def update_weather_url( hash )
|
496
|
+
if hash['weather.url'] and match = hash['weather.url'].scan(%r[\Ahttp://weather.noaa.gov/weather/current/(\w{4,4}).html\z])[0]
|
497
|
+
hash['weather.url'] = Weather::STATION_URL_TEMPLATE % match[0]
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
451
501
|
# www configuration interface
|
452
502
|
def configure_weather
|
453
503
|
if( @mode == 'saveconf' ) then
|
454
504
|
# weather.url
|
455
|
-
|
505
|
+
station = Weather::extract_station_id( @cgi.params['weather.url'][0] )
|
506
|
+
if station
|
507
|
+
@conf['weather.url'] = Weather::STATION_URL_TEMPLATE % station
|
508
|
+
else
|
509
|
+
@conf['weather.url'] = @cgi.params['weather.url'][0]
|
510
|
+
end
|
456
511
|
# weather.tz
|
457
512
|
tz = @cgi.params['weather.tz'][0]
|
458
513
|
unless tz.empty? then # need more checks
|
@@ -469,6 +524,7 @@ def configure_weather
|
|
469
524
|
end
|
470
525
|
end
|
471
526
|
end
|
527
|
+
update_weather_url( @conf )
|
472
528
|
weather_configure_html( @conf )
|
473
529
|
end
|
474
530
|
|
@@ -482,13 +538,13 @@ _END
|
|
482
538
|
end
|
483
539
|
|
484
540
|
if not feed? and not @options['weather.in_title'] then
|
485
|
-
add_body_enter_proc do |date|
|
541
|
+
add_body_enter_proc do |date|
|
486
542
|
weather( date )
|
487
543
|
end
|
488
544
|
end
|
489
545
|
|
490
546
|
if not feed? and @options['weather.in_title'] then
|
491
|
-
add_title_proc do |date, title|
|
547
|
+
add_title_proc do |date, title|
|
492
548
|
title + weather( date, false )
|
493
549
|
end
|
494
550
|
end
|
data/misc/plugin/whatsnew.rb
CHANGED
@@ -44,7 +44,7 @@ server.add_handler('blogger.newPost') do |appkey, blogid, username, password, co
|
|
44
44
|
title,body = content.split(/\n/,2)
|
45
45
|
index = diary.add_section(title, body)
|
46
46
|
src = diary.to_src
|
47
|
-
|
47
|
+
|
48
48
|
@cgi.params.delete 'date'
|
49
49
|
@cgi.params['old'] = [postid]
|
50
50
|
@cgi.params['hide'] = diary.visible? ? [] : ['true']
|
@@ -78,7 +78,7 @@ server.add_handler('blogger.editPost') do |appkey, postid, username, password, c
|
|
78
78
|
index = index.to_i
|
79
79
|
time = Time::local( year, month, day ) + 12*60*60
|
80
80
|
diary = tdiary[time]
|
81
|
-
|
81
|
+
|
82
82
|
src = ''
|
83
83
|
i = 0
|
84
84
|
diary.each_section {|sec|
|
@@ -90,7 +90,7 @@ server.add_handler('blogger.editPost') do |appkey, postid, username, password, c
|
|
90
90
|
end
|
91
91
|
src << sec.to_src
|
92
92
|
}
|
93
|
-
|
93
|
+
|
94
94
|
@cgi.params.delete 'date'
|
95
95
|
@cgi.params['old'] = [postid[0,8]]
|
96
96
|
@cgi.params['hide'] = diary.visible? ? [] : ['true']
|
@@ -123,10 +123,10 @@ server.add_handler('blogger.deletePost') do |appkey, postid, username, password|
|
|
123
123
|
tdiary = ::TDiary::TDiaryDay::new( @cgi, "day.rhtml", @conf )
|
124
124
|
time = Time::local( year, month, day ) + 12*60*60
|
125
125
|
diary = tdiary[time]
|
126
|
-
|
126
|
+
|
127
127
|
diary.delete_section(index)
|
128
128
|
src = diary.to_src
|
129
|
-
|
129
|
+
|
130
130
|
@cgi.params.delete 'date'
|
131
131
|
@cgi.params['old'] = [postid[0,8]]
|
132
132
|
@cgi.params['hide'] = diary.visible? ? [] : ['true']
|
@@ -216,10 +216,10 @@ server.add_handler('metaWeblog.newPost') do |blogid, username, password, content
|
|
216
216
|
tdiary = ::TDiary::TDiaryDay::new( @cgi, "day.rhtml", @conf )
|
217
217
|
time = Time::local( year, month, day ) + 12*60*60
|
218
218
|
diary = tdiary[time] || tdiary.instance_variable_get(:@io).diary_factory(time, '', '', @conf.style)
|
219
|
-
|
219
|
+
|
220
220
|
index = diary.add_section(content['title'], content['description'])
|
221
221
|
src = diary.to_src
|
222
|
-
|
222
|
+
|
223
223
|
@cgi.params.delete 'date'
|
224
224
|
@cgi.params['old'] = [postid]
|
225
225
|
@cgi.params['hide'] = diary.visible? ? [] : ['true']
|
@@ -250,7 +250,7 @@ server.add_handler('metaWeblog.editPost') do |postid, username, password, conten
|
|
250
250
|
index = index.to_i
|
251
251
|
time = Time::local( year, month, day ) + 12*60*60
|
252
252
|
diary = tdiary[time]
|
253
|
-
|
253
|
+
|
254
254
|
src = ''
|
255
255
|
i = 0
|
256
256
|
diary.each_section {|sec|
|
@@ -261,7 +261,7 @@ server.add_handler('metaWeblog.editPost') do |postid, username, password, conten
|
|
261
261
|
end
|
262
262
|
src << sec.to_src
|
263
263
|
}
|
264
|
-
|
264
|
+
|
265
265
|
@cgi.params.delete 'date'
|
266
266
|
@cgi.params['old'] = [postid[0,8]]
|
267
267
|
@cgi.params['hide'] = diary.visible? ? [] : ['true']
|
@@ -478,7 +478,7 @@ server.add_handler('mt.setPostCategories') do |postid, username, password, categ
|
|
478
478
|
diary = tdiary[time]
|
479
479
|
|
480
480
|
@cgi.params.delete 'date'
|
481
|
-
|
481
|
+
|
482
482
|
src = ''
|
483
483
|
i = 0
|
484
484
|
diary.each_section {|sec|
|
@@ -494,7 +494,7 @@ server.add_handler('mt.setPostCategories') do |postid, username, password, categ
|
|
494
494
|
end
|
495
495
|
src << sec.to_src
|
496
496
|
}
|
497
|
-
|
497
|
+
|
498
498
|
@cgi.params['old'] = [postid[0,8]]
|
499
499
|
@cgi.params['hide'] = diary.visible? ? [] : ['true']
|
500
500
|
@cgi.params['title'] = [diary.title]
|
@@ -404,14 +404,14 @@ def theme_convert ( fname, hash )
|
|
404
404
|
end
|
405
405
|
end
|
406
406
|
}
|
407
|
-
end
|
407
|
+
end
|
408
408
|
end
|
409
409
|
|
410
410
|
rcss = File::readlines( "append.rcss" ).join
|
411
411
|
File.open( fname.sub( /\.css/i, "-2.css" ), "a" ) do |f|
|
412
412
|
f.write( ERB::new( rcss ).result( binding ) )
|
413
413
|
end
|
414
|
-
end
|
414
|
+
end
|
415
415
|
|
416
416
|
while cssname = ARGV.shift
|
417
417
|
unless cssname
|
@@ -422,7 +422,7 @@ while cssname = ARGV.shift
|
|
422
422
|
begin
|
423
423
|
simplify_css( cssname )
|
424
424
|
rescue
|
425
|
-
File.delete( cssname.sub( /\.css/i, "-simple.css" ) )
|
425
|
+
File.delete( cssname.sub( /\.css/i, "-simple.css" ) )
|
426
426
|
puts "Error!: #{$!}"
|
427
427
|
next
|
428
428
|
end
|