tdiary-contrib 4.0.2.1 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +16 -12
- data/lib/extensions/contrib.rb +16 -0
- data/lib/tdiary-contrib.rb +2 -12
- data/lib/tdiary/contrib/version.rb +2 -2
- data/plugin/coderay.rb +74 -0
- data/plugin/image_ex.rb +15 -17
- data/plugin/makerss_category.rb +2 -2
- data/plugin/makerss_comment.rb +2 -2
- data/plugin/nhk_program_info.rb +104 -0
- data/plugin/profile.rb +4 -19
- data/plugin/search-bing.rb +10 -6
- data/spec/apple_webclip_spec.rb +3 -3
- data/spec/gist_spec.rb +1 -1
- data/spec/github_link_spec.rb +4 -4
- data/spec/google_analytics_spec.rb +3 -3
- data/spec/jdate_spec.rb +1 -1
- data/spec/jmonth_spec.rb +1 -1
- data/spec/jyear_spec.rb +1 -1
- data/spec/my_hotentry_spec.rb +8 -8
- data/spec/openid_spec.rb +34 -34
- data/spec/opensearch_ad_spec.rb +5 -5
- data/spec/profile_spec.rb +15 -15
- data/spec/title_anchor_spec.rb +4 -4
- data/spec/twitter_js_spec.rb +8 -8
- data/spec/youtube_spec.rb +1 -1
- data/tdiary-contrib.gemspec +1 -2
- data/util/image-gallery/misc/plugin/recent_image.rb +2 -2
- metadata +8 -9
- data/plugin/search-default.rb +0 -269
- data/util/tdiarysearch/README.en +0 -53
- data/util/tdiarysearch/README.ja +0 -99
- data/util/tdiarysearch/search.rb +0 -504
data/util/tdiarysearch/README.en
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
### This tool is obsolete,
|
2
|
-
### use alternative plugin: plugin/search-default.rb.
|
3
|
-
### This tool will be deleted in the near future.
|
4
|
-
|
5
|
-
|
6
|
-
tdiarysearch README
|
7
|
-
===================
|
8
|
-
|
9
|
-
This is tdiarysearch, simple tDiary search interface.
|
10
|
-
|
11
|
-
|
12
|
-
Installation and setup
|
13
|
-
----------------------
|
14
|
-
|
15
|
-
1. Copy search.rb aside of tDiary's index.rb.
|
16
|
-
|
17
|
-
$ ls
|
18
|
-
index.rb*
|
19
|
-
search.rb*
|
20
|
-
tdiary.conf
|
21
|
-
update.rb*
|
22
|
-
|
23
|
-
2. Make search.rb executable.
|
24
|
-
|
25
|
-
$ chmod a+x search.rb
|
26
|
-
|
27
|
-
3. (Optional) Adjust shebang (#!) line of search.rb.
|
28
|
-
|
29
|
-
4. (Optional) If you'd like, edit embedded paramter in
|
30
|
-
search.rb and turn on query logging.
|
31
|
-
|
32
|
-
5. Add following HTML form in your tDiary header:
|
33
|
-
|
34
|
-
<form method="post" action="search.rb" class="searchform">
|
35
|
-
<input type="text" name="q" size="20" value="">
|
36
|
-
<input type="submit" value="Search">
|
37
|
-
</form>
|
38
|
-
|
39
|
-
6. Done.
|
40
|
-
|
41
|
-
|
42
|
-
License
|
43
|
-
-------
|
44
|
-
|
45
|
-
GNU GPL, General Public License version 2.
|
46
|
-
|
47
|
-
|
48
|
-
Contact
|
49
|
-
-------
|
50
|
-
|
51
|
-
Minero Aoki <aamine@loveruby.net>
|
52
|
-
http://i.loveruby.net/en/
|
53
|
-
|
data/util/tdiarysearch/README.ja
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
■■このツールは最新のtDiaryに追従していません。
|
2
|
-
■■検索機能はプラグインとして実装されるようになったため、
|
3
|
-
■■同等の機能はplugin/search-default.rbで実現しています。
|
4
|
-
■■このツールは近々削除する予定です。
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
tdiarysearch README
|
9
|
-
===================
|
10
|
-
|
11
|
-
tDiary簡単検索CGIです。
|
12
|
-
あらかじめインデックスを作る必要がないので、
|
13
|
-
一般的な検索エンジンに比べてインストールが
|
14
|
-
圧倒的に簡単です。また、書いた直後の日記も
|
15
|
-
検索対象になるという長所があります。
|
16
|
-
|
17
|
-
|
18
|
-
必要環境
|
19
|
-
--------
|
20
|
-
|
21
|
-
* テキスト形式のデータベースを使っていること (tDiary 1.5 以降)
|
22
|
-
* tDiary が動いているサーバに独自の CGI を追加する権限があること
|
23
|
-
|
24
|
-
|
25
|
-
セットアップ
|
26
|
-
------------
|
27
|
-
|
28
|
-
1. search.rb を tDiary の index.rb の隣にコピーします。
|
29
|
-
必要なら index.rb と同じようにシンボリックリンクを
|
30
|
-
張ったり名前を変えたりしてください。
|
31
|
-
|
32
|
-
2. CGI として実行可能にします。
|
33
|
-
|
34
|
-
$ chmod a+x search.rb
|
35
|
-
|
36
|
-
3. 必要なら #! のパスを合わせます。
|
37
|
-
|
38
|
-
4. (オプション) search.rb 先頭のパラメータを変更して
|
39
|
-
クエリーログを有効にしてください。
|
40
|
-
※ クエリーログの詳細については後述
|
41
|
-
|
42
|
-
5. 自分の tDiary の好きな場所 (例えばヘッダ) に以下の
|
43
|
-
フォームを加えてください。
|
44
|
-
|
45
|
-
<form method="post" action="search.rb" class="searchform">
|
46
|
-
<input type="text" name="q" size="20" value="">
|
47
|
-
<input type="submit" value="Search">
|
48
|
-
</form>
|
49
|
-
|
50
|
-
以上です。
|
51
|
-
|
52
|
-
|
53
|
-
検索のしかた
|
54
|
-
------------
|
55
|
-
|
56
|
-
tdiarysearch はトピックごとに AND 検索を行います。
|
57
|
-
指定した語は空白で分割され、全単語がトピック内のテキストに
|
58
|
-
全て含まれる場合にそのトピックを検索結果にリストします。
|
59
|
-
|
60
|
-
AND 以外の演算はサポートしません。
|
61
|
-
|
62
|
-
また rev 1.8 の段階ではまだツッコミが検索できません。
|
63
|
-
近いうちに追加します。
|
64
|
-
|
65
|
-
|
66
|
-
クエリーログ
|
67
|
-
------------
|
68
|
-
|
69
|
-
クエリーログ (query log) というのは、検索語のログの
|
70
|
-
ことです。このログが存在すると他の人が何を検索したのか
|
71
|
-
見られるようになります。クエリーログを有効にするには、
|
72
|
-
search.rb 内の定数 LOGGING を true にしてください。
|
73
|
-
|
74
|
-
CGI からログを見られるようにするには、search.rb に
|
75
|
-
パラメータ history=on を付けて呼びます。例えば
|
76
|
-
次のリンクを日記に入れておくと、リンクをたどるだけで
|
77
|
-
日記から最近の検索ログが見られます。
|
78
|
-
|
79
|
-
<a href="search.rb?history=on">[検索ログ]</a>
|
80
|
-
|
81
|
-
なお、クエリーログは tDiary のデータディレクトリに search.log
|
82
|
-
という名前で作成されます。特にローテーション処理はしていないので、
|
83
|
-
適当な間隔でローテートしてください。
|
84
|
-
|
85
|
-
|
86
|
-
連絡先
|
87
|
-
------
|
88
|
-
|
89
|
-
青木峰郎 (あおき・みねろう)
|
90
|
-
Minero Aoki <aamine@loveruby.net>
|
91
|
-
http://i.loveruby.net/w/tdiarysearch.html
|
92
|
-
|
93
|
-
バグ報告は以下のどこかにお願いします。
|
94
|
-
|
95
|
-
* Wiki 上のバグ報告ページ
|
96
|
-
http://i.loveruby.net/w/tdiarysearchBugs.html
|
97
|
-
* tdiary-devel ML
|
98
|
-
* 直接メール
|
99
|
-
|
data/util/tdiarysearch/search.rb
DELETED
@@ -1,504 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# tdiarysearch
|
4
|
-
#
|
5
|
-
# Copyright (C) 2003-2005 Minero Aoki
|
6
|
-
#
|
7
|
-
# This program is free software.
|
8
|
-
# You can distribute/modify this program under the terms of
|
9
|
-
# the GNU GPL, General Public License version 2.
|
10
|
-
#
|
11
|
-
# $originalId: search.rb,v 1.14 2005/07/27 07:16:07 aamine Exp $
|
12
|
-
#
|
13
|
-
# Project home page: http://i.loveruby.net/w/tdiarysearch.html
|
14
|
-
#
|
15
|
-
|
16
|
-
#
|
17
|
-
# Static Configurations
|
18
|
-
#
|
19
|
-
|
20
|
-
LOGGING = false
|
21
|
-
LOGFILE_NAME = 'search.log'
|
22
|
-
DEBUG = $DEBUG
|
23
|
-
|
24
|
-
#
|
25
|
-
# HTML Templates
|
26
|
-
#
|
27
|
-
|
28
|
-
def unindent(str)
|
29
|
-
str.gsub(/^#{str[/\A(?:\t+| +)/]}/, '')
|
30
|
-
end
|
31
|
-
|
32
|
-
HEADER = unindent <<'EOS'
|
33
|
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
34
|
-
<html lang="ja">
|
35
|
-
<head>
|
36
|
-
<meta http-equiv="Content-Type" content="text/html; charset=<%= TDIARY_ENCODING %>">
|
37
|
-
<meta http-equiv="Content-Language" content="ja">
|
38
|
-
<meta name="robots" content="noindex">
|
39
|
-
<link rel="stylesheet" href="theme/base.css" type="text/css" media="all">
|
40
|
-
<link rel="stylesheet" href="theme/<%= theme %>/<%= theme %>.css" title="<%= theme %>" type="text/css" media="all">
|
41
|
-
<title>tDiary Search</title>
|
42
|
-
</head>
|
43
|
-
<body>
|
44
|
-
<div class="whole-content">
|
45
|
-
EOS
|
46
|
-
|
47
|
-
FOOTER = unindent <<'EOS'
|
48
|
-
</div>
|
49
|
-
</body>
|
50
|
-
</html>
|
51
|
-
EOS
|
52
|
-
|
53
|
-
SEARCH_FORM = unindent <<"EOS"
|
54
|
-
<form method="post" action="#{File.basename(__FILE__)}">
|
55
|
-
<input type="text" name="q" size="20" value="<%= patterns.map {|re| escape(re.source) }.join(' ') %>">
|
56
|
-
<input type="submit" value="Search">
|
57
|
-
<%
|
58
|
-
if theme
|
59
|
-
%><input type="hidden" name="theme" value="on"><%
|
60
|
-
end
|
61
|
-
%>
|
62
|
-
</form>
|
63
|
-
EOS
|
64
|
-
|
65
|
-
SEARCH_PAGE = unindent <<"EOS"
|
66
|
-
<h1>tDiary Search</h1>
|
67
|
-
#{SEARCH_FORM}
|
68
|
-
EOS
|
69
|
-
|
70
|
-
TOO_MANY_HITS = 50
|
71
|
-
|
72
|
-
SEARCH_RESULT = unindent <<"EOS"
|
73
|
-
<h1>tDiary Search: Search Result</h1>
|
74
|
-
#{SEARCH_FORM}
|
75
|
-
<%
|
76
|
-
nhits = 0
|
77
|
-
toomanyhits = false
|
78
|
-
match_components(patterns) {|diary, fragment, component|
|
79
|
-
nhits += 1
|
80
|
-
if nhits > TOO_MANY_HITS
|
81
|
-
toomanyhits = true
|
82
|
-
break
|
83
|
-
end
|
84
|
-
%>
|
85
|
-
<div class="day">
|
86
|
-
<h2><a href="<%= url(diary, fragment) %>"><%= diary.y_m_d %></a></h2>
|
87
|
-
<div class="body">
|
88
|
-
<div class="section">
|
89
|
-
<p><%= short_html(component) %></p>
|
90
|
-
</div>
|
91
|
-
</div>
|
92
|
-
</div><%
|
93
|
-
}
|
94
|
-
%>
|
95
|
-
<p><%= toomanyhits ? 'too many hits.' : nhits.to_s+' hits.' %></p>
|
96
|
-
#{SEARCH_FORM}
|
97
|
-
EOS
|
98
|
-
|
99
|
-
SEARCH_ERROR = unindent <<"EOS"
|
100
|
-
#{SEARCH_FORM}
|
101
|
-
<%= escape(reason) %>.
|
102
|
-
EOS
|
103
|
-
|
104
|
-
HISTORY = unindent <<"EOS"
|
105
|
-
<h1>tDiary Search: Search History</h1>
|
106
|
-
#{SEARCH_FORM}
|
107
|
-
<ul>
|
108
|
-
<%
|
109
|
-
recent_queries.sort_by {|t,q| -t.to_i }.each do |time, query|
|
110
|
-
%><li><%= time.strftime('%Y-%m-%d %H:%M:%S') %> | <a href="#{File.basename(__FILE__)}?q=<%= escape_url(query) %>"><%= escape(query) %></a></li>
|
111
|
-
<%
|
112
|
-
end
|
113
|
-
%></ul>
|
114
|
-
#{SEARCH_FORM}
|
115
|
-
EOS
|
116
|
-
|
117
|
-
#
|
118
|
-
# Main
|
119
|
-
#
|
120
|
-
|
121
|
-
if File.symlink?(__FILE__)
|
122
|
-
tdiarylib = File.dirname(File.readlink(__FILE__))
|
123
|
-
else
|
124
|
-
tdiarylib = File.dirname(__FILE__)
|
125
|
-
end
|
126
|
-
$:.unshift tdiarylib
|
127
|
-
require 'tdiary'
|
128
|
-
require 'tdiary/io/default'
|
129
|
-
require 'erb'
|
130
|
-
|
131
|
-
TDIARY_ENCODING = (TDIARY_VERSION >= '2.3.0') ? 'utf-8' : 'euc-jp'
|
132
|
-
|
133
|
-
class WrongQuery < StandardError; end
|
134
|
-
|
135
|
-
Z_SPACE = "\241\241" # zen-kaku space
|
136
|
-
|
137
|
-
BEGIN { $stdout.binmode }
|
138
|
-
|
139
|
-
def main
|
140
|
-
$KCODE = TDIARY_ENCODING
|
141
|
-
cgi = CGI.new
|
142
|
-
@config = TDiary::Config.new(cgi)
|
143
|
-
@config.options['apply_plugin'] = true
|
144
|
-
html = '<html><head><title></title></head><body><p>error</p></body></html>'
|
145
|
-
begin
|
146
|
-
html = generate_page(cgi)
|
147
|
-
ensure
|
148
|
-
send_html cgi, html
|
149
|
-
end
|
150
|
-
exit 0
|
151
|
-
end
|
152
|
-
|
153
|
-
def generate_page(cgi)
|
154
|
-
query = nil
|
155
|
-
begin
|
156
|
-
theme = @config.theme
|
157
|
-
if LOGGING and File.file?(query_log()) and cgi.valid?('history')
|
158
|
-
return history_page(theme)
|
159
|
-
end
|
160
|
-
begin
|
161
|
-
return search_form_page(theme) unless cgi.valid?('q')
|
162
|
-
initialize_tdiary_plugins cgi
|
163
|
-
query = @config.to_native([cgi.params['q']].flatten.compact.join(' '))
|
164
|
-
patterns = setup_patterns(query)
|
165
|
-
html = search_result_page(theme, patterns)
|
166
|
-
save_query(query, query_log()) if LOGGING
|
167
|
-
return html
|
168
|
-
rescue WrongQuery => err
|
169
|
-
return search_error_page(theme, (patterns || []), err.message)
|
170
|
-
end
|
171
|
-
rescue Exception => err
|
172
|
-
html = ''
|
173
|
-
html << HEADER
|
174
|
-
html << "<pre>\n"
|
175
|
-
html << 'q=' << escape(query) << "\n" if query
|
176
|
-
html << escape(err.class.name) << "\n" if DEBUG
|
177
|
-
html << escape(err.message) << "\n"
|
178
|
-
html << err.backtrace.map {|i| escape(i) }.join("\n") if DEBUG
|
179
|
-
html << "</pre>\n"
|
180
|
-
html << FOOTER
|
181
|
-
return html
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def send_html(cgi, html)
|
186
|
-
print cgi.header('status' => '200 OK',
|
187
|
-
'type' => 'text/html',
|
188
|
-
'charset' => TDIARY_ENCODING,
|
189
|
-
'Content-Length' => html.length.to_s,
|
190
|
-
'Cache-Control' => 'no-cache',
|
191
|
-
'Pragma' => 'no-cache')
|
192
|
-
print html unless cgi.request_method == 'HEAD'
|
193
|
-
end
|
194
|
-
|
195
|
-
def setup_patterns(query)
|
196
|
-
patterns = split_string(query).map {|pat|
|
197
|
-
check_pattern pat
|
198
|
-
Regexp.new( Regexp.quote(pat), Regexp::IGNORECASE, TDIARY_ENCODING )
|
199
|
-
}
|
200
|
-
raise WrongQuery, 'no pattern' if patterns.empty?
|
201
|
-
raise WrongQuery, 'too many sub patterns' if patterns.length > 8
|
202
|
-
patterns
|
203
|
-
end
|
204
|
-
|
205
|
-
def check_pattern(pat)
|
206
|
-
raise WrongQuery, 'no pattern' unless pat
|
207
|
-
raise WrongQuery, 'empty pattern' if pat.empty?
|
208
|
-
raise WrongQuery, "pattern too short: #{pat}" if pat.length < 2
|
209
|
-
raise WrongQuery, 'pattern too long' if pat.length > 128
|
210
|
-
end
|
211
|
-
|
212
|
-
def split_string(str)
|
213
|
-
str.split(/[\s#{Z_SPACE}]+/ou).reject {|w| w.empty? }
|
214
|
-
end
|
215
|
-
|
216
|
-
def save_query(query, file)
|
217
|
-
File.open(file, 'a') {|f|
|
218
|
-
begin
|
219
|
-
f.flock(File::LOCK_EX)
|
220
|
-
f.puts "#{Time.now.to_i}: #{query.dump}"
|
221
|
-
ensure
|
222
|
-
f.flock(File::LOCK_UN)
|
223
|
-
end
|
224
|
-
}
|
225
|
-
end
|
226
|
-
|
227
|
-
#
|
228
|
-
# eRuby Dispatchers and Helper Routines
|
229
|
-
#
|
230
|
-
|
231
|
-
def search_form_page(theme)
|
232
|
-
patterns = []
|
233
|
-
ERB.new(HEADER + SEARCH_FORM + FOOTER).result(binding())
|
234
|
-
end
|
235
|
-
|
236
|
-
def search_result_page(theme, patterns)
|
237
|
-
ERB.new(HEADER + SEARCH_RESULT + FOOTER).result(binding())
|
238
|
-
end
|
239
|
-
|
240
|
-
def search_error_page(theme, patterns, reason)
|
241
|
-
ERB.new(HEADER + SEARCH_ERROR + FOOTER).result(binding())
|
242
|
-
end
|
243
|
-
|
244
|
-
def history_page(theme)
|
245
|
-
patterns = []
|
246
|
-
ERB.new(HEADER + HISTORY + FOOTER).result(binding())
|
247
|
-
end
|
248
|
-
|
249
|
-
def query_log
|
250
|
-
"#{@config.data_path}#{LOGFILE_NAME}"
|
251
|
-
end
|
252
|
-
|
253
|
-
N_SHOW_QUERY_MAX = 20
|
254
|
-
|
255
|
-
def recent_queries
|
256
|
-
return unless File.file?(query_log())
|
257
|
-
File.readlines(query_log()).reverse[0, N_SHOW_QUERY_MAX].map {|line|
|
258
|
-
time, q = *line.split(/:/, 2)
|
259
|
-
[Time.at(time.to_i), eval(q)]
|
260
|
-
}
|
261
|
-
end
|
262
|
-
|
263
|
-
INF = 1 / 0.0
|
264
|
-
|
265
|
-
def match_components(patterns)
|
266
|
-
foreach_diary_from_latest do |diary|
|
267
|
-
next unless diary.visible?
|
268
|
-
num = 1
|
269
|
-
diary.each_section do |sec|
|
270
|
-
if patterns.all? {|re| re =~ sec.to_src }
|
271
|
-
yield diary, fragment('p', num), sec
|
272
|
-
end
|
273
|
-
num += 1
|
274
|
-
end
|
275
|
-
diary.each_visible_comment(INF) do |cmt, num|
|
276
|
-
if patterns.all? {|re| re =~ cmt.body }
|
277
|
-
yield diary, fragment('c', num), cmt
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
def fragment(type, num)
|
284
|
-
sprintf('%s%02d', type, num)
|
285
|
-
end
|
286
|
-
|
287
|
-
#
|
288
|
-
# tDiary Implementation Dependent
|
289
|
-
#
|
290
|
-
|
291
|
-
def foreach_diary_from_latest(&block)
|
292
|
-
foreach_data_file(@config.data_path.sub(%r</+\z>, '')) do |path|
|
293
|
-
read_diaries(path).sort_by {|diary| diary.date }.reverse_each(&block)
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
def foreach_data_file(data_path, &block)
|
298
|
-
Dir.glob("#{data_path}/[0-9]*/*.td2").sort.reverse_each do |path|
|
299
|
-
yield path.untaint
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
def read_diaries(path)
|
304
|
-
d = nil
|
305
|
-
diaries = {}
|
306
|
-
load_tdiary_textdb(path) do |header, body|
|
307
|
-
d = diary_class(header['Format']).new(header['Date'], '', body)
|
308
|
-
d.show(header['Visible'] != 'false')
|
309
|
-
diaries[d.ymd] = d
|
310
|
-
end
|
311
|
-
(Years[d.y] ||= []).push(d.m) if d
|
312
|
-
load_comments diaries, path
|
313
|
-
diaries.values
|
314
|
-
end
|
315
|
-
|
316
|
-
DIARY_CLASS_CACHE = {}
|
317
|
-
|
318
|
-
def diary_class(style)
|
319
|
-
c = DIARY_CLASS_CACHE[style]
|
320
|
-
return c if c
|
321
|
-
require "tdiary/style/#{style.downcase}_style.rb"
|
322
|
-
c = eval("TDiary::#{style.capitalize}Diary")
|
323
|
-
c.__send__(:include, DiaryClassDelta)
|
324
|
-
DIARY_CLASS_CACHE[style] = c
|
325
|
-
c
|
326
|
-
end
|
327
|
-
|
328
|
-
module DiaryClassDelta
|
329
|
-
def ymd
|
330
|
-
date().strftime('%Y%m%d')
|
331
|
-
end
|
332
|
-
|
333
|
-
def y_m_d
|
334
|
-
date().strftime('%Y-%m-%d')
|
335
|
-
end
|
336
|
-
|
337
|
-
def y
|
338
|
-
'%04d' % date().year
|
339
|
-
end
|
340
|
-
|
341
|
-
def m
|
342
|
-
'%02d' % date().month
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
|
-
def load_comments(diaries, path)
|
347
|
-
cmtfile = path.sub(/2\z/, 'c')
|
348
|
-
return unless File.file?(cmtfile)
|
349
|
-
load_tdiary_textdb(cmtfile) do |header, body|
|
350
|
-
c = TDiary::Comment.new(header['Name'], header['Mail'], body,
|
351
|
-
Time.at(header['Last-Modified'].to_i))
|
352
|
-
c.show = (header['Visible'] != 'false')
|
353
|
-
d = diaries[header['Date']]
|
354
|
-
d.add_comment c if d
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
def load_tdiary_textdb(path)
|
359
|
-
File.open(path) {|f|
|
360
|
-
ver = f.gets.strip
|
361
|
-
raise "unkwnown format: #{ver}" unless ver == 'TDIARY2.00.00' or ver == 'TDIARY2.01.00'
|
362
|
-
f.each('') do |header|
|
363
|
-
h = {}
|
364
|
-
header.untaint.strip.each do |line|
|
365
|
-
n, v = *line.split(':', 2)
|
366
|
-
h[n.strip] = v.strip
|
367
|
-
end
|
368
|
-
yield h, f.gets("\n.\n").chomp(".\n").untaint
|
369
|
-
end
|
370
|
-
}
|
371
|
-
end
|
372
|
-
|
373
|
-
def short_html(component)
|
374
|
-
# Section classes do not have common superclass, we can't use class here.
|
375
|
-
case component.class.name
|
376
|
-
when /Section/
|
377
|
-
section = component
|
378
|
-
if section.subtitle
|
379
|
-
sprintf('%s<br>%s',
|
380
|
-
tdiary2text(section.subtitle_to_html),
|
381
|
-
tdiary2text(section.body_to_html))
|
382
|
-
else
|
383
|
-
tdiary2text(section.body_to_html)
|
384
|
-
end
|
385
|
-
when /Comment/
|
386
|
-
cmt = component
|
387
|
-
shorten(escape((cmt.name + ': ' + cmt.body)))
|
388
|
-
else
|
389
|
-
raise "must not happen: #{component.class}"
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
def tdiary2text(html)
|
394
|
-
re = Regexp.new('<[^>]*>', Regexp::EXTENDED, TDIARY_ENCODING)
|
395
|
-
shorten(apply_tdiary_plugins(html).gsub(re, ''))
|
396
|
-
end
|
397
|
-
|
398
|
-
Years = {}
|
399
|
-
|
400
|
-
TDiary::Plugin.__send__(:public, :apply_plugin)
|
401
|
-
def apply_tdiary_plugins(html)
|
402
|
-
@plugin.apply_plugin(html, false)
|
403
|
-
end
|
404
|
-
|
405
|
-
@plugin = nil
|
406
|
-
|
407
|
-
def initialize_tdiary_plugins(cgi)
|
408
|
-
@plugin = TDiary::Plugin.new('conf' => @config,
|
409
|
-
'secure' => false,
|
410
|
-
'diaries' => {},
|
411
|
-
'cgi' => cgi,
|
412
|
-
'index' => @config.index,
|
413
|
-
'years' => Years,
|
414
|
-
'cache_path' => @config.cache_path ||
|
415
|
-
@config.data_path)
|
416
|
-
end
|
417
|
-
|
418
|
-
#
|
419
|
-
# Utils
|
420
|
-
#
|
421
|
-
|
422
|
-
HTML_ESCAPE_TABLE = {
|
423
|
-
'&' => '&',
|
424
|
-
'<' => '<',
|
425
|
-
'>' => '>',
|
426
|
-
'"' => '"'
|
427
|
-
}
|
428
|
-
|
429
|
-
def escape(str)
|
430
|
-
tbl = HTML_ESCAPE_TABLE
|
431
|
-
str.gsub(/[&"<>]/) {|ch| tbl[ch] }
|
432
|
-
end
|
433
|
-
|
434
|
-
def escape_url(u)
|
435
|
-
escape(urlencode(u))
|
436
|
-
end
|
437
|
-
|
438
|
-
def urlencode(str)
|
439
|
-
str.gsub(/[^\w-]/n) {|ch| sprintf('%%%02x', ch[0]) }
|
440
|
-
end
|
441
|
-
|
442
|
-
def shorten(str)
|
443
|
-
re = Regexp.new('\A.{0,120}', Regexp::MULTILINE, TDIARY_ENCODING)
|
444
|
-
str.slice(re)
|
445
|
-
end
|
446
|
-
|
447
|
-
def url(diary, fragment)
|
448
|
-
if ( html_anchor_enabled? )
|
449
|
-
"#{@config.index}#{diary.ymd}.html\##{fragment}"
|
450
|
-
else
|
451
|
-
"#{@config.index}?date=#{diary.ymd}\##{fragment}"
|
452
|
-
end
|
453
|
-
end
|
454
|
-
|
455
|
-
def html_anchor_enabled?
|
456
|
-
if ( @html_anchor.nil? )
|
457
|
-
@html_anchor = @config.options2['sp.selected'].include?( 'html_anchor.rb' )
|
458
|
-
end
|
459
|
-
|
460
|
-
return @html_anchor
|
461
|
-
end
|
462
|
-
|
463
|
-
#
|
464
|
-
# Old Ruby Compatibility
|
465
|
-
#
|
466
|
-
|
467
|
-
if RUBY_VERSION < '1.8.0'
|
468
|
-
class String
|
469
|
-
remove_method :slice
|
470
|
-
def slice(re, n = 0)
|
471
|
-
m = re.match(self) or return nil
|
472
|
-
m[n]
|
473
|
-
end
|
474
|
-
end
|
475
|
-
end
|
476
|
-
|
477
|
-
unless Array.method_defined?(:all?)
|
478
|
-
module Enumerable
|
479
|
-
def all?
|
480
|
-
each do |i|
|
481
|
-
return false unless yield(i)
|
482
|
-
end
|
483
|
-
true
|
484
|
-
end
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
unless Array.method_defined?(:sort_by)
|
489
|
-
module Enumerable
|
490
|
-
def sort_by
|
491
|
-
map {|i| [yield(i), i] }.sort.map {|val, i| i }
|
492
|
-
end
|
493
|
-
end
|
494
|
-
end
|
495
|
-
|
496
|
-
unless MatchData.method_defined?(:captures)
|
497
|
-
class MatchData
|
498
|
-
def captures
|
499
|
-
to_a()[1..-1]
|
500
|
-
end
|
501
|
-
end
|
502
|
-
end
|
503
|
-
|
504
|
-
main
|