tdiary 4.0.2 → 4.0.2.20140201

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/Gemfile +8 -7
  4. data/Gemfile.lock +17 -15
  5. data/config.ru +0 -2
  6. data/doc/INSTALL-paas.md +17 -5
  7. data/misc/plugin/amazon/amazonimg.rb +1 -1
  8. data/misc/plugin/category.rb +7 -7
  9. data/misc/plugin/image.rb +4 -1
  10. data/misc/plugin/search-default.rb +269 -0
  11. data/misc/theme_convert/theme_convert.rb +3 -3
  12. data/plugin/50sp.rb +3 -2
  13. data/spec/acceptance/append_comment_spec.rb +8 -8
  14. data/spec/acceptance/append_diary_spec.rb +9 -9
  15. data/spec/acceptance/save_conf_comment_spec.rb +7 -7
  16. data/spec/acceptance/save_conf_default_spec.rb +31 -31
  17. data/spec/acceptance/save_conf_dnsbl_spec.rb +28 -28
  18. data/spec/acceptance/save_conf_referer_spec.rb +6 -6
  19. data/spec/acceptance/save_conf_security_spec.rb +37 -37
  20. data/spec/acceptance/support/helpers.rb +8 -8
  21. data/spec/acceptance/update_diary_spec.rb +21 -21
  22. data/spec/acceptance/view_category_spec.rb +5 -5
  23. data/spec/acceptance/view_comment_spec.rb +6 -6
  24. data/spec/acceptance/view_diary_spec.rb +12 -12
  25. data/spec/acceptance/view_referer_spec.rb +3 -3
  26. data/spec/acceptance_helper.rb +2 -2
  27. data/spec/core/configuration_spec.rb +1 -1
  28. data/spec/core/io/default_spec.rb +30 -2
  29. data/spec/core/plugin_spec.rb +1 -1
  30. data/tdiary/application/configuration.rb +0 -1
  31. data/tdiary/application/extensions/omniauth.rb +1 -1
  32. data/tdiary/application.rb +6 -9
  33. data/tdiary/cli.rb +6 -6
  34. data/tdiary/configuration.rb +2 -2
  35. data/tdiary/extensions/core.rb +18 -0
  36. data/tdiary/extensions.rb +6 -0
  37. data/tdiary/io/base.rb +11 -7
  38. data/tdiary/lang/ja.rb +2 -2
  39. data/tdiary/server.rb +1 -1
  40. data/tdiary/version.rb +1 -1
  41. data/tdiary.rb +2 -1
  42. data/test/test_plugin_helper.rb +54 -10
  43. data/test/test_plugin_helper_test.rb +27 -5
  44. data/test/weather_test.rb +26 -22
  45. data/tmp/.gitkeep +0 -0
  46. metadata +7 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e3b1d5ff9c5be93ee04e88c9d5e1a1894e7e42dd
4
- data.tar.gz: dc3abc8a1d49859c4db89e70c1f84c34d8176227
3
+ metadata.gz: 3c52de43dc119883d82cc39f570b3b2f5999b96d
4
+ data.tar.gz: 517e13ad91be78f16ae61c3d4fd678d9d29e327c
5
5
  SHA512:
6
- metadata.gz: a4fd13995035a6a6ac9a4a62cee6fdd567d9c0d5a4c3fbe88368d7ba082bc339dc918149164a2dc9fc0824ed1e8a63f9cc378a69b322f32ebab6832288811ab5
7
- data.tar.gz: 5b7c08feb7f14e2cd6b002cd7a5105dcb6dde0d8b3278a11f8f22736ad6f54e39eb657b99b0467135c0b0faa1fbf7ecaebec4852aa3a48206019b3065b3c329e
6
+ metadata.gz: 857ecaf2c9a4466f323710df41d0341dbb19bb02332c96ede67ec6f5966d20e25de11215ac3d7dbea86df89e6f6ffce2c3dc1fc2f0fd6569f36efd483833e897
7
+ data.tar.gz: f60cfac1eec83552533d86cf30b4ce6468470eb54d2009570afd70903c51807b259fc386cf77e78a89b78dbab5ae45ad0d503fc1509145afd0ca01a913939b4d
data/.travis.yml CHANGED
@@ -6,6 +6,8 @@ rvm:
6
6
  - 1.9.3
7
7
  - 2.0.0
8
8
 
9
+ cache: bundler
10
+
9
11
  # ignored --deployment option
10
12
  bundler_args: ""
11
13
 
data/Gemfile CHANGED
@@ -21,23 +21,24 @@ group :server do
21
21
  end
22
22
 
23
23
  group :development do
24
- gem 'pit', :require => false
25
- gem 'racksh', :require => false
24
+ gem 'pit', require: false
25
+ gem 'racksh', require: false
26
26
  gem 'rake'
27
+ gem 'redcarpet'
27
28
 
28
29
  group :test do
29
30
  gem 'pry'
30
31
  gem 'tapp'
31
- gem 'test-unit', :require => 'test/unit'
32
+ gem 'test-unit', require: 'test/unit'
32
33
  gem 'rspec'
33
- gem 'capybara', :require => 'capybara/rspec'
34
+ gem 'capybara', require: 'capybara/rspec'
34
35
  gem 'selenium-webdriver'
35
36
  gem 'launchy'
36
37
  gem 'sequel'
37
38
  gem 'sqlite3'
38
- gem 'jasmine'
39
- gem 'simplecov', :require => false
40
- gem 'coveralls', :require => false
39
+ gem 'jasmine', '~> 1.3'
40
+ gem 'simplecov', require: false
41
+ gem 'coveralls', require: false
41
42
  end
42
43
  end
43
44
 
data/Gemfile.lock CHANGED
@@ -2,19 +2,19 @@ GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
4
  addressable (2.3.5)
5
- capybara (2.2.0)
5
+ capybara (2.2.1)
6
6
  mime-types (>= 1.16)
7
7
  nokogiri (>= 1.3.3)
8
8
  rack (>= 1.0.0)
9
9
  rack-test (>= 0.5.4)
10
10
  xpath (~> 2.0)
11
- childprocess (0.3.9)
11
+ childprocess (0.4.0)
12
12
  ffi (~> 1.0, >= 1.0.11)
13
13
  coderay (1.1.0)
14
14
  coffee-script (2.2.0)
15
15
  coffee-script-source
16
16
  execjs
17
- coffee-script-source (1.6.3)
17
+ coffee-script-source (1.7.0)
18
18
  coveralls (0.7.0)
19
19
  multi_json (~> 1.3)
20
20
  rest-client
@@ -23,10 +23,10 @@ GEM
23
23
  thor
24
24
  daemons (1.1.9)
25
25
  diff-lcs (1.2.5)
26
- docile (1.1.1)
26
+ docile (1.1.2)
27
27
  eventmachine (1.0.3)
28
28
  execjs (2.0.2)
29
- fastimage (1.5.4)
29
+ fastimage (1.6.0)
30
30
  addressable (~> 2.3, >= 2.3.5)
31
31
  ffi (1.9.3)
32
32
  hike (1.2.3)
@@ -41,13 +41,13 @@ GEM
41
41
  addressable (~> 2.3)
42
42
  libv8 (3.16.14.3)
43
43
  method_source (0.8.2)
44
- mime-types (2.0)
44
+ mime-types (2.1)
45
45
  mini_portile (0.5.2)
46
- multi_json (1.8.2)
47
- nokogiri (1.6.0)
46
+ multi_json (1.8.4)
47
+ nokogiri (1.6.1)
48
48
  mini_portile (~> 0.5.0)
49
49
  pit (0.0.7)
50
- pry (0.9.12.4)
50
+ pry (0.9.12.6)
51
51
  coderay (~> 1.0)
52
52
  method_source (~> 0.8)
53
53
  slop (~> 3.4)
@@ -57,7 +57,8 @@ GEM
57
57
  racksh (1.0.0)
58
58
  rack (>= 1.0)
59
59
  rack-test (>= 0.5)
60
- rake (10.1.0)
60
+ rake (10.1.1)
61
+ redcarpet (3.0.0)
61
62
  ref (1.0.5)
62
63
  rest-client (1.6.7)
63
64
  mime-types (>= 1.16)
@@ -69,13 +70,13 @@ GEM
69
70
  rspec-expectations (2.14.4)
70
71
  diff-lcs (>= 1.1.3, < 2.0)
71
72
  rspec-mocks (2.14.4)
72
- rubyzip (1.0.0)
73
- selenium-webdriver (2.37.0)
73
+ rubyzip (1.1.0)
74
+ selenium-webdriver (2.39.0)
74
75
  childprocess (>= 0.2.5)
75
76
  multi_json (~> 1.0)
76
- rubyzip (~> 1.0.0)
77
+ rubyzip (~> 1.0)
77
78
  websocket (~> 1.0.4)
78
- sequel (4.4.0)
79
+ sequel (4.6.0)
79
80
  simplecov (0.8.2)
80
81
  docile (~> 1.1.0)
81
82
  multi_json
@@ -116,13 +117,14 @@ DEPENDENCIES
116
117
  coveralls
117
118
  fastimage
118
119
  hikidoc
119
- jasmine
120
+ jasmine (~> 1.3)
120
121
  launchy
121
122
  pit
122
123
  pry
123
124
  rack
124
125
  racksh
125
126
  rake
127
+ redcarpet
126
128
  rspec
127
129
  selenium-webdriver
128
130
  sequel
data/config.ru CHANGED
@@ -1,6 +1,4 @@
1
1
  $:.unshift( File::dirname( __FILE__ ).untaint )
2
- require 'tdiary'
3
- require 'tdiary/environment'
4
2
  require 'tdiary/application'
5
3
 
6
4
  use ::Rack::Reloader unless ENV['RACK_ENV'] == 'production'
data/doc/INSTALL-paas.md CHANGED
@@ -27,10 +27,16 @@ tDiary の最新版を取得します。
27
27
  git clone git://github.com/tdiary/tdiary-core.git
28
28
  ```
29
29
 
30
- heroku コマンドを用いて Heroku でアプリケーションを作成します。なお、Heroku のアカウント作成方法は本ドキュメントでは省略します。tDiary のルートディレクトリ(Gemfile が存在する箇所) で以下のコマンドを実行します。
30
+ 続いて、依存するライブラリをインストールするために bundle install コマンドを実行します。
31
31
 
32
32
  ```
33
33
  % cd tdiary-core
34
+ % bundle install
35
+ ```
36
+
37
+ heroku コマンドを用いて Heroku でアプリケーションを作成します。なお、Heroku のアカウント作成方法は本ドキュメントでは省略します。tDiary のルートディレクトリ(Gemfile が存在する箇所) で以下のコマンドを実行します。
38
+
39
+ ```
34
40
  % heroku apps:create [アプリケーション名]
35
41
  ```
36
42
 
@@ -51,7 +57,7 @@ heroku コマンドを用いて Heroku でアプリケーションを作成し
51
57
  日記更新時に必要となるユーザー名とパスワードを保存する .htpasswd ファイルを作成します。この情報は重要なので、外部には公開しないでください。
52
58
 
53
59
  ```
54
- % rake auth:password:create
60
+ % bundle exec rake auth:password:create
55
61
  ```
56
62
 
57
63
  ここまでの変更内容を deploy ブランチにコミットし、Heroku にアプリケーションを転送します。
@@ -73,10 +79,16 @@ tDiary の最新版を取得します。
73
79
  git clone git://github.com/tdiary/tdiary-core.git
74
80
  ```
75
81
 
76
- sqale.jp にアクセスして新しいアプリケーションを作成します。作成後にアプリケーションの URL を git のリモートリポジトリに追加します。tDiary のルートディレクトリ(Gemfile が存在する箇所) で以下のコマンドを実行します。
82
+ 続いて、依存するライブラリをインストールするために bundle install コマンドを実行します。
77
83
 
78
84
  ```
79
85
  % cd tdiary-core
86
+ % bundle install
87
+ ```
88
+
89
+ sqale.jp にアクセスして新しいアプリケーションを作成します。作成後にアプリケーションの URL を git のリモートリポジトリに追加します。tDiary のルートディレクトリ(Gemfile が存在する箇所) で以下のコマンドを実行します。
90
+
91
+ ```
80
92
  % git remote add sqale ssh://sqale@gateway.sqale.jp:2222/[username]/[application].git
81
93
  ```
82
94
 
@@ -97,7 +109,7 @@ username と application の値は別途読み替えてください。続いて
97
109
  日記更新時に必要となるユーザー名とパスワードを保存する .htpasswd ファイルを作成します。この情報は重要なので、外部には公開しないでください。
98
110
 
99
111
  ```
100
- % rake auth:password:create
112
+ % bundle exec rake auth:password:create
101
113
  ```
102
114
 
103
115
  dot.env ファイルを .env にリネームして、データベースの接続情報を記入します。データベースの接続情報は sqale のアプリケーションダッシュボードから参照してください。接続情報は以下の形式で記入します。
@@ -109,7 +121,7 @@ DATABASE_URL=mysql2://username:password@hostname/database
109
121
  sqale では javascript や css ファイルを作業ディレクトリの public/assets 配下に置く必要があります。以下のコマンドを実行して対象のファイルをコピーしてください。
110
122
 
111
123
  ```
112
- rake assets:copy
124
+ % bundle exec rake assets:copy
113
125
  ```
114
126
 
115
127
  ここまでの変更内容を deploy ブランチにコミットし、Heroku にアプリケーションを転送します。
@@ -66,7 +66,7 @@ def amazon_call_ecs( asin, country = nil )
66
66
  url << "&Version=#{@amazon_require_version}"
67
67
 
68
68
  timeout( 10 ) do
69
- open( url, :proxy => @proxy ) {|f| f.read}
69
+ open( url, proxy: @proxy ) {|f| f.read}
70
70
  end
71
71
  end
72
72
 
@@ -78,8 +78,8 @@ def category_navi
78
78
  result = ''
79
79
  case mode
80
80
  when :year, :half, :quarter, :month
81
- all_diary = Category::Info.new(@cgi, @years, @conf, :year => -1, :month => -1)
82
- all = Category::Info.new(@cgi, @years, @conf, :category => ['ALL'], :year => -1, :month => -1)
81
+ all_diary = Category::Info.new(@cgi, @years, @conf, year: -1, month: -1)
82
+ all = Category::Info.new(@cgi, @years, @conf, category: ['ALL'], year: -1, month: -1)
83
83
  result << category_navi_anchor(info.prev, @conf['category.prev_' + mode.to_s], mobile)
84
84
  result << category_navi_anchor(info.next, @conf['category.next_' + mode.to_s], mobile)
85
85
  unless mobile then
@@ -87,17 +87,17 @@ def category_navi
87
87
  result << category_navi_anchor(all, @conf['category.all'])
88
88
  end
89
89
  when :all
90
- year = Category::Info.new(@cgi, @years, @conf, :year => Time.now.year.to_s)
91
- half = Category::Info.new(@cgi, @years, @conf, :year => Time.now.year.to_s, :month => "#{((Time.now.month - 1) / 6 + 1)}H")
92
- quarter = Category::Info.new(@cgi, @years, @conf, :year => Time.now.year.to_s, :month => "#{((Time.now.month - 1) / 3 + 1)}Q")
93
- month = Category::Info.new(@cgi, @years, @conf, :year => Time.now.year.to_s, :month => '%02d' % Time.now.month)
90
+ year = Category::Info.new(@cgi, @years, @conf, year: Time.now.year.to_s)
91
+ half = Category::Info.new(@cgi, @years, @conf, year: Time.now.year.to_s, month: "#{((Time.now.month - 1) / 6 + 1)}H")
92
+ quarter = Category::Info.new(@cgi, @years, @conf, year: Time.now.year.to_s, month: "#{((Time.now.month - 1) / 3 + 1)}Q")
93
+ month = Category::Info.new(@cgi, @years, @conf, year: Time.now.year.to_s, month: '%02d' % Time.now.month)
94
94
  result << category_navi_anchor(year, @conf['category.this_year'], mobile)
95
95
  result << category_navi_anchor(half, @conf['category.this_half'], mobile)
96
96
  result << category_navi_anchor(quarter, @conf['category.this_quarter'], mobile)
97
97
  result << category_navi_anchor(month, @conf['category.this_month'], mobile)
98
98
  end
99
99
  if !info.category.include?('ALL') and !mobile then
100
- all_category = Category::Info.new(@cgi, @years, @conf, :category => ['ALL'])
100
+ all_category = Category::Info.new(@cgi, @years, @conf, category: ['ALL'])
101
101
  result << category_navi_anchor(all_category, @conf['category.all_category'])
102
102
  end
103
103
  result
data/misc/plugin/image.rb CHANGED
@@ -120,10 +120,13 @@ end
120
120
  #
121
121
  # initialize
122
122
  #
123
- @image_dir = @options && @options['image.dir'] || './images/'
123
+ @image_dir = (@options && @options['image.dir']) || File.join(TDiary.server_root, @cgi.is_a?(RackCGI) ? 'public/images' : 'images')
124
124
  @image_dir.chop! if /\/$/ =~ @image_dir
125
+ FileUtils.mkdir_p @image_dir unless File.exist?(@image_dir)
126
+
125
127
  @image_url = @options && @options['image.url'] || "#{base_url}images/"
126
128
  @image_url.chop! if /\/$/ =~ @image_url
129
+
127
130
  @image_maxwidth = @options && @options['image.maxwidth'] || nil
128
131
 
129
132
  add_body_enter_proc do |date|
@@ -0,0 +1,269 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # search-default.rb - site search plugin sample using DefaultIO.
4
+ #
5
+ # Copyright (C) 2003-2005 Minero Aoki
6
+ # Copyright (C) 2012, TADA Tadashi <t@tdtds.jp>
7
+ # You can redistribute it and/or modify it under GPL2.
8
+ #
9
+ #
10
+
11
+ def search_title
12
+ '全文検索'
13
+ end
14
+
15
+ class WrongQuery < StandardError; end
16
+
17
+ module DefaultIOSearch
18
+
19
+ module_function
20
+ def setup_patterns(query)
21
+ patterns = split_string(query).map {|pat|
22
+ check_pattern pat
23
+ Regexp.new( Regexp.quote(pat), Regexp::IGNORECASE )
24
+ }
25
+ raise WrongQuery, 'no pattern' if patterns.empty?
26
+ raise WrongQuery, 'too many sub patterns' if patterns.length > 8
27
+ patterns
28
+ end
29
+
30
+ def check_pattern(pat)
31
+ raise WrongQuery, 'no pattern' unless pat
32
+ raise WrongQuery, 'empty pattern' if pat.empty?
33
+ raise WrongQuery, "pattern too short: #{pat}" if pat.length < 2
34
+ raise WrongQuery, 'pattern too long' if pat.length > 128
35
+ end
36
+
37
+ def split_string(str)
38
+ str.split(/[\s ]+/ou).reject {|w| w.empty? }
39
+ end
40
+
41
+ INF = 1 / 0.0
42
+
43
+ def match_components(patterns, data_path)
44
+ foreach_diary_from_latest(data_path) do |diary|
45
+ next unless diary.visible?
46
+ num = 1
47
+ diary.each_section do |sec|
48
+ if patterns.all? {|re| re =~ sec.to_src }
49
+ yield diary, fragment('p', num), sec
50
+ end
51
+ num += 1
52
+ end
53
+ diary.each_visible_comment(INF) do |cmt, num|
54
+ if patterns.all? {|re| re =~ cmt.body }
55
+ yield diary, fragment('c', num), cmt
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ def fragment(type, num)
62
+ sprintf('%s%02d', type, num)
63
+ end
64
+
65
+ #
66
+ # tDiary Implementation Dependent
67
+ #
68
+ def foreach_diary_from_latest(data_path, &block)
69
+ foreach_data_file(data_path.sub(%r</+\z>, '')) do |path|
70
+ read_diaries(path).sort_by {|diary| diary.date }.reverse_each(&block)
71
+ end
72
+ end
73
+
74
+ def foreach_data_file(data_path, &block)
75
+ Dir.glob("#{data_path}/[0-9]*/*.td2").sort.reverse_each do |path|
76
+ yield path.untaint
77
+ end
78
+ end
79
+
80
+ def read_diaries(path)
81
+ d = nil
82
+ diaries = {}
83
+ load_tdiary_textdb(path) do |header, body|
84
+ begin
85
+ d = diary_class(header['Format']).new(header['Date'], '', body)
86
+ rescue ArgumentError
87
+ next
88
+ end
89
+ d.show(header['Visible'] != 'false')
90
+ diaries[d.ymd] = d
91
+ end
92
+ (Years[d.y] ||= []).push(d.m) if d
93
+ load_comments diaries, path
94
+ diaries.values
95
+ end
96
+
97
+ DIARY_CLASS_CACHE = {}
98
+
99
+ def diary_class(style)
100
+ c = DIARY_CLASS_CACHE[style]
101
+ return c if c
102
+ if TDiary.const_defined?('Style')
103
+ require "tdiary/style/#{style.downcase}.rb"
104
+ c = eval("TDiary::Style::#{style.capitalize}Diary")
105
+ else
106
+ require "tdiary/style/#{style.downcase}_style.rb"
107
+ c = eval("TDiary::#{style.capitalize}Diary")
108
+ end
109
+ c.__send__(:include, DiaryClassDelta)
110
+ DIARY_CLASS_CACHE[style] = c
111
+ c
112
+ end
113
+
114
+ module DiaryClassDelta
115
+ def ymd
116
+ date().strftime('%Y%m%d')
117
+ end
118
+
119
+ def y_m_d
120
+ date().strftime('%Y-%m-%d')
121
+ end
122
+
123
+ def y
124
+ '%04d' % date().year
125
+ end
126
+
127
+ def m
128
+ '%02d' % date().month
129
+ end
130
+ end
131
+
132
+ def load_comments(diaries, path)
133
+ cmtfile = path.sub(/2\z/, 'c')
134
+ return unless File.file?(cmtfile)
135
+ load_tdiary_textdb(cmtfile) do |header, body|
136
+ c = TDiary::Comment.new(header['Name'], header['Mail'], body,
137
+ Time.at(header['Last-Modified'].to_i))
138
+ c.show = (header['Visible'] != 'false')
139
+ d = diaries[header['Date']]
140
+ d.add_comment c if d
141
+ end
142
+ end
143
+
144
+ def load_tdiary_textdb(path)
145
+ File.open(path) {|f|
146
+ ver = f.gets.strip
147
+ raise "unkwnown format: #{ver}" unless ver == 'TDIARY2.00.00' or ver == 'TDIARY2.01.00'
148
+ f.each('') do |header|
149
+ h = {}
150
+ header.untaint.strip.each_line do |line|
151
+ begin
152
+ n, v = *line.split(':', 2)
153
+ rescue ArgumentError
154
+ next
155
+ end
156
+ h[n.strip] = v.strip
157
+ end
158
+ body = f.gets("\n.\n").chomp(".\n").untaint
159
+ yield h, body
160
+ end
161
+ }
162
+ end
163
+
164
+ def short_html(component)
165
+ # Section classes do not have common superclass, we can't use class here.
166
+ case component.class.name
167
+ when /Section/
168
+ section = component
169
+ if section.subtitle
170
+ sprintf('%s<br>%s',
171
+ tdiary2text(section.subtitle_to_html),
172
+ tdiary2text(section.body_to_html))
173
+ else
174
+ tdiary2text(section.body_to_html)
175
+ end
176
+ when /Comment/
177
+ cmt = component
178
+ shorten(escape((cmt.name + ': ' + cmt.body)))
179
+ else
180
+ raise "must not happen: #{component.class}"
181
+ end
182
+ end
183
+
184
+ def tdiary2text(html)
185
+ re = Regexp.new('<[^>]*>', Regexp::EXTENDED)
186
+ shorten(apply_tdiary_plugins(html).gsub(re, ''))
187
+ end
188
+
189
+ Years = {}
190
+
191
+ TDiary::Plugin.__send__(:public, :apply_plugin)
192
+ def apply_tdiary_plugins(html)
193
+ #@plugin.apply_plugin(html, false)
194
+ html
195
+ end
196
+
197
+ @plugin = nil
198
+
199
+ #
200
+ # Utils
201
+ #
202
+ HTML_ESCAPE_TABLE = {
203
+ '&' => '&amp;',
204
+ '<' => '&lt;',
205
+ '>' => '&gt;',
206
+ '"' => '&quot;'
207
+ }
208
+
209
+ def escape(str)
210
+ tbl = HTML_ESCAPE_TABLE
211
+ str.gsub(/[&"<>]/) {|ch| tbl[ch] }
212
+ end
213
+
214
+ def shorten(str, len = 200)
215
+ matched = str.gsub( /\n/, ' ' ).scan( /^.{0,#{len - 3}}/u )[0]
216
+ if $'.nil? || $'.empty?
217
+ matched
218
+ else
219
+ matched + '...'
220
+ end
221
+ end
222
+ end
223
+
224
+ def search_input_form( q )
225
+ r = <<-HTML
226
+ <form method="GET" action="#{@conf.index}"><div>
227
+ 検索キーワード:
228
+ <input name="q" value="#{h q}">
229
+ <input type="submit" value="OK">
230
+ </div></form>
231
+ HTML
232
+ end
233
+
234
+ def search_result
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>|
237
+ end
238
+
239
+ query = CGI::unescape( @cgi.params['q'][0] )
240
+ start = CGI::unescape( @cgi.params['start'][0] || '0' ).to_i
241
+
242
+ begin
243
+ patterns = DefaultIOSearch::setup_patterns(query)
244
+ r = search_input_form( query )
245
+
246
+ r << '<dl class="search-result autopagerize_page_element">'
247
+ count = 0
248
+ too_many = false
249
+ DefaultIOSearch::match_components(patterns, @conf.data_path) do |diary, fragment, component|
250
+ count += 1
251
+ if count > 50 # TO MANY HITS
252
+ too_many = true
253
+ break
254
+ end
255
+ href = @conf.index + anchor( "#{diary.ymd}#{fragment}" )
256
+ r << %Q|<dt><a href="#{href}">#{h diary.y_m_d}</a></dt>|
257
+ r << %Q|<dd>#{DefaultIOSearch::short_html(component)}</dd>|
258
+ end
259
+ r << '</dl>'
260
+
261
+ r << '<div class="search-navi">'
262
+ r << "<p>#{too_many ? 'too many' : count} hits.</p>"
263
+ r << '</div>'
264
+
265
+ r
266
+ rescue WrongQuery
267
+ search_input_form( query ) + %Q|<p class="message">#{$!.message}</p>|
268
+ end
269
+ end
@@ -167,12 +167,12 @@ racc_goto_default = [
167
167
  racc_token_table = {
168
168
  false => 0,
169
169
  Object.new => 1,
170
- :IDENT => 2,
170
+ IDENT: 2,
171
171
  ":" => 3,
172
172
  "{" => 4,
173
173
  "}" => 5,
174
- :QUOTE => 6,
175
- :EOL => 7 }
174
+ QUOTE: 6,
175
+ EOL: 7 }
176
176
 
177
177
  racc_use_result_var = true
178
178
 
data/plugin/50sp.rb CHANGED
@@ -8,8 +8,9 @@ SP_PREFIX = 'sp'
8
8
  end
9
9
  @sp_path << "#{TDiary::PATH}/misc/plugin" if @sp_path.include?('misc/plugin')
10
10
 
11
- # FIXME: dirty hack, it should create TDiary::Server::Config.plugin_path
12
- TDiary::Contrib::Plugin.setup( @sp_path ) if defined?(TDiary::Contrib)
11
+ @sp_path.concat TDiary::Extensions::constants.map {|extension|
12
+ TDiary::Extensions::const_get( extension ).sp_path
13
+ }.flatten.compact.uniq
13
14
 
14
15
  # get plugin option
15
16
  def sp_option( key )
@@ -6,8 +6,8 @@ feature 'ツッコミの更新' do
6
6
  append_default_diary
7
7
  visit '/'
8
8
  click_link 'ツッコミを入れる'
9
- fill_in "name", :with => "alpha"
10
- fill_in "body", :with => <<-BODY
9
+ fill_in "name", with: "alpha"
10
+ fill_in "body", with: <<-BODY
11
11
  こんにちは!こんにちは!
12
12
  BODY
13
13
 
@@ -22,7 +22,7 @@ BODY
22
22
  page.should have_content "こんにちは!こんにちは!"
23
23
  }
24
24
  today = Date.today.strftime('%Y年%m月%d日')
25
- page.find('h2', :text => today).click_link today
25
+ page.find('h2', text: today).click_link today
26
26
  within('div.day div.comment div.commentbody') {
27
27
  within('div.commentator'){
28
28
  t = Time.now
@@ -38,8 +38,8 @@ BODY
38
38
  append_default_comment
39
39
  visit "/"
40
40
  click_link 'ツッコミを入れる'
41
- fill_in "name", :with => "bravo"
42
- fill_in "body", :with => <<-BODY
41
+ fill_in "name", with: "bravo"
42
+ fill_in "body", with: <<-BODY
43
43
  こんばんは!こんばんは!
44
44
  BODY
45
45
 
@@ -55,7 +55,7 @@ BODY
55
55
  }
56
56
 
57
57
  today = Date.today.strftime('%Y年%m月%d日')
58
- page.find('h2', :text => today).click_link today
58
+ page.find('h2', text: today).click_link today
59
59
  within('div.day div.comment div.commentbody') {
60
60
  t = Time.now
61
61
  page.should have_content "%04d年%02d月%02d日" % [t.year, t.month, t.day]
@@ -70,8 +70,8 @@ BODY
70
70
  append_default_diary
71
71
  visit '/'
72
72
  click_link 'ツッコミを入れる'
73
- fill_in "name", :with => "alpha"
74
- fill_in "body", :with => <<-BODY
73
+ fill_in "name", with: "alpha"
74
+ fill_in "body", with: <<-BODY
75
75
  こんにちは!こんにちは!
76
76
  BODY
77
77