bbiff 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd30ca75c040f69a2d133839bacf119a872c9061
4
- data.tar.gz: 83e817bfd77e054edf0503945580e43534e87e61
3
+ metadata.gz: 037966c6b4adc37eb5630c02746d1c0a6ef609ed
4
+ data.tar.gz: 87886e10129ef9ae257a78c52396bc0e3324ab39
5
5
  SHA512:
6
- metadata.gz: 3252f846fd7ccd4675456df483f400b962e98b5c9217a5d8e378c6468a7e62c8773a48ae600e23971622e08624351d1c5bccc7690d213e9024cec8e58f9a4c0b
7
- data.tar.gz: cf3e620a32d8fa61be5f2453082591932ed234cdc948966375d51177090a8eb667f3215a94780ef6c616f214577b2748ebe449fc04e46b53de2abf3396d559b8
6
+ metadata.gz: 1116585b2aa1dd80258bf3e8d99bba5cac503790539faeb5e5fea99b6bfedb9ea1601b59f0b3e061264f758a0500e62ef8f611cc5a45fc99ac974703344f9c73
7
+ data.tar.gz: 7eb9d8a7d563b58cc52534604e7af91a2d40f416eb66bbe8ed5ac60cd3963030fd244d320c134e17da3c82b1b27a23aacafd0f7723f51c6e442598d89e7b3706
data/README.md CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  ## 必要なもの
4
4
 
5
- notify-send コマンド
5
+ デスクトップに通知ポップアップを表示する、notify-send コマンド。Ubuntu
6
+ では以下のようにインストールできます。
6
7
 
7
8
  sudo apt-get install libnotify-bin
8
9
 
@@ -14,8 +15,10 @@ notify-send コマンド
14
15
 
15
16
  bbiff スレッドのURL レス通知を始める番号
16
17
 
17
- スレッドのURLは http://jbbs.shitaraba.net/bbs/read.cgi/カテゴリ/板ID/スレID/
18
- の形式です。
18
+ スレッドのURLはしたらば掲示板の場合、
19
+ `http://jbbs.shitaraba.net/bbs/read.cgi/カテゴリ/板ID/スレID/`、2ちゃ
20
+ んねる互換掲示板の場合は、`http://ホスト名/test/read.cgi/板名/スレID/`
21
+ のような形式になります。
19
22
 
20
23
  単に
21
24
 
@@ -23,16 +26,11 @@ notify-send コマンド
23
26
 
24
27
  とすると、前回監視したスレッドを監視します。
25
28
 
26
- ## 開発・TODO
27
-
28
- - .travis.ymlでテストするなら要編集
29
- - moduleの中にまとめるべきかも
30
-
31
29
  ## リリース
32
30
 
33
31
  ver 0.1.0
34
32
  * gem 化した。(DoG-peer さん)
35
-
33
+
36
34
  ver 0.1.2
37
35
  * notify-send コマンドがインストールされていない場合は echo コマンド
38
36
  を利用するようにした。(raduwen さん)
@@ -53,6 +51,10 @@ ver 0.2.2
53
51
  * 最後に読み込んだスレの情報が無い状態で、引数なしで bbiff を起動し
54
52
  た時にエラーになっていたのを修正。
55
53
 
54
+ ver 0.3.0
55
+ * 2ちゃんねる互換掲示板に対応したつもり。
56
+ * 日付の相対表示を辞めた。
57
+
56
58
  ## 作者
57
59
 
58
60
  予定地 <plonk@piano.email.ne.jp>
@@ -1,141 +1,414 @@
1
1
  require 'net/http'
2
2
  require 'uri'
3
+ require 'pp' if $DEBUG
3
4
 
4
5
  module Bbs
5
6
 
6
- class C板
7
- def initialize(カテゴリ, 掲示板番号)
8
- @カテゴリ = カテゴリ
9
- @掲示板番号 = 掲示板番号
10
- @設定URL = URI.parse( "http://jbbs.shitaraba.net/bbs/api/setting.cgi/#{カテゴリ}/#{掲示板番号}/" )
11
- @スレ一覧URL = URI.parse( "http://jbbs.shitaraba.net/#{カテゴリ}/#{掲示板番号}/subject.txt" )
12
- end
7
+ class Post
8
+ class << self
9
+ def from_s(str)
10
+ Post.new(*str.split('<>', 5))
11
+ end
12
+ end
13
13
 
14
- def dat_url(スレッド番号)
15
- return URI.parse("http://jbbs.shitaraba.net/bbs/rawmode.cgi/#{@カテゴリ}/#{@掲示板番号}/#{スレッド番号}/")
16
- end
14
+ attr_reader :no, :name, :mail, :body, :date
17
15
 
18
- def 設定
19
- r = ダウンロード(@設定URL)
20
- return 設定をパーズする(r.force_encoding("EUC-JP").encode("UTF-8"))
21
- end
16
+ def initialize(no, name, mail, date, body)
17
+ @no = no.to_i
18
+ @name = name
19
+ @mail = mail
20
+ @date = date
21
+ @body = body
22
+ end
22
23
 
23
- def スレ一覧
24
- r = ダウンロード(@スレ一覧URL)
25
- return r.force_encoding("EUC-JP").encode("UTF-8")
26
- end
24
+ # 削除された時のフィールドの値は、掲示板の設定によるなぁ。
25
+ # def deleted?
26
+ # @date == '<削除>'
27
+ # end
27
28
 
28
- def dat(スレッド番号)
29
- url = dat_url(スレッド番号)
30
- r = ダウンロード(url)
31
- return r.force_encoding("EUC-JP").encode("UTF-8")
32
- end
29
+ def to_s
30
+ [no, name, mail, date, body].join('<>')
31
+ end
33
32
 
34
- def thread(スレッド番号)
35
- threads.find { |t| t.id == スレッド番号 }
36
33
  end
37
34
 
38
- def threads
39
- スレ一覧.each_line.map do |line|
40
- fail 'スレ一覧のフォーマットが変です' unless line =~ /^(\d+)\.cgi,(.+?)\((\d+)\)$/
41
- id, title, last = $1.to_i, $2, $3.to_i
42
- Thread.new(self, id, title, last)
35
+ class Downloader
36
+ class DownloadFailure < StandardError
37
+ attr_reader :response
38
+
39
+ def initialize(response)
40
+ @response = response
41
+ end
43
42
  end
44
- end
45
43
 
46
- def ダウンロード(url)
47
- 応答 = Net::HTTP.start(url.host, url.port) { |http|
48
- http.get(url.path)
49
- }
50
- return 応答.body
51
- end
44
+ class Resource
45
+ attr_reader :data
52
46
 
53
- private
47
+ def initialize(data)
48
+ self.data = data
49
+ end
54
50
 
55
- def 設定をパーズする(文字列)
56
- 文字列.each_line.map { |line|
57
- line.chomp.split(/=/, 2)
58
- }.to_h
59
- end
60
- end
51
+ def data=(new_data)
52
+ type_check(new_data)
53
+ @data = new_data.dup.freeze
54
+ end
61
55
 
62
- class Post
63
- attr_reader :no, :name, :mail, :body
56
+ private
64
57
 
65
- def self.from_line(line)
66
- no, name, mail, date, body, = line.split('<>', 6)
67
- Post.new(no, name, mail, date, body)
68
- end
58
+ # ASCII-8BIT エンコーディングの String に限定する。
59
+ def type_check(data)
60
+ unless data.is_a? String
61
+ raise TypeError, 'not a string'
62
+ end
63
+ unless data.encoding == Encoding::ASCII_8BIT
64
+ raise ArgumentError, "encoding not ASCII-8BIT (#{data.encoding})"
65
+ end
66
+ end
67
+ end
69
68
 
70
- def initialize(no, name, mail, date, body)
71
- @no = no.to_i
72
- @name = name
73
- @mail = mail
74
- @date = date
75
- @body = body
76
- end
69
+ attr_reader :encoding
77
70
 
78
- def date
79
- str2time(@date)
80
- end
71
+ def initialize(encoding = 'UTF-8')
72
+ @encoding = encoding
73
+ @resource_cache = {}
74
+ end
81
75
 
82
- def to_s
83
- [no, name, mail, @date, body, '', ''].join('<>')
84
- end
76
+ # ASCII-8BIT エンコーディングの文字列を返す。
77
+ def download_binary(uri)
78
+ resource = @resource_cache[uri]
79
+ if resource
80
+ Net::HTTP.start(uri.host, uri.port) do |http|
81
+ request = Net::HTTP::Get.new(uri)
82
+ request['range'] = "bytes=#{resource.data.bytesize}-"
83
+ response = http.request(request)
84
+ response.body.force_encoding('ASCII-8BIT')
85
+ pp response.code if $DEBUG
86
+ pp response.to_hash if $DEBUG
87
+ case response
88
+ when Net::HTTPPartialContent
89
+ p :partial if $DEBUG
90
+ resource.data += response.body
91
+ when Net::HTTPRequestedRangeNotSatisfiable
92
+ p :not_satisfiable if $DEBUG
93
+ # 多分DATは更新されていない
94
+ when Net::HTTPOK
95
+ p :ok if $DEBUG
96
+ @resource_cache[uri] = Resource.new(response.body)
97
+ return response.body
98
+ else
99
+ raise DownloadFailure.new(response)
100
+ end
101
+ return resource.data
102
+ end
103
+ else
104
+ p :no_resource_yet if $DEBUG
105
+ body = download_binary_nocache(uri)
106
+ @resource_cache[uri] = Resource.new(body)
107
+ return body
108
+ end
109
+ end
85
110
 
86
- private
111
+ def download_binary_nocache(uri)
112
+ response = nil
113
+ Net::HTTP.start(uri.host, uri.port) do |http|
114
+ request = Net::HTTP::Get.new(uri)
115
+ response = http.request(request)
116
+ response.body.force_encoding('ASCII-8BIT')
117
+ pp response.code if $DEBUG
118
+ pp response.to_hash if $DEBUG
119
+ case response
120
+ when Net::HTTPOK
121
+ else
122
+ raise DownloadFailure.new(response)
123
+ end
124
+ end
125
+ return response.body
126
+ end
87
127
 
88
- def str2time(str)
89
- if str =~ %r{^(\d{4})/(\d{2})/(\d{2})\(.\) (\d{2}):(\d{2}):(\d{2})$}
90
- y, mon, d, h, min, sec = [$1, $2, $3, $4, $5, $6].map(&:to_i)
91
- Time.new(y, mon, d, h, min, sec)
92
- else
93
- fail ArgumentError
128
+ def download_text(uri)
129
+ # dup は重要。
130
+ download_binary(uri).dup.force_encoding(encoding).encode('UTF-8')
94
131
  end
95
132
  end
96
- end
97
133
 
98
- class Thread
99
- attr_reader :id, :title, :last, :board
134
+ class BoardBase
135
+ private_class_method :new
136
+ attr_reader :settings_url
100
137
 
101
- def initialize(board, id, title, last = 1)
102
- @board = board
103
- @id = id
104
- @title = title
105
- @last = last
138
+ def initialize(text_encoding)
139
+ @downloader = Downloader.new(text_encoding)
140
+ end
141
+
142
+ def thread(thread_num)
143
+ threads.find { |t| t.id == thread_num }
144
+ end
145
+
146
+ def settings
147
+ return parse_settings(download_text(@settings_url))
148
+ end
149
+
150
+ def thread_list
151
+ return download_text(@thread_list_url)
152
+ end
153
+
154
+ def dat(thread_num)
155
+ return download_text(dat_url(thread_num))
156
+ end
157
+
158
+ def threads
159
+ thread_list.each_line.map do |line|
160
+ create_thread_from_line(line)
161
+ end
162
+ end
163
+
164
+ # 抽象メソッド
165
+ def create_thread_from_line(_line)
166
+ raise 'unimplemented'
167
+ end
168
+
169
+ def dat_url(_thread_num)
170
+ raise 'unimplemented'
171
+ end
172
+
173
+ protected
174
+
175
+ def download_binary(url)
176
+ @downloader.download_binary(url)
177
+ end
178
+
179
+ def download_text(url)
180
+ @downloader.download_text(url)
181
+ end
182
+
183
+ def parse_settings(string)
184
+ string.each_line.map { |line|
185
+ line.chomp.split(/=/, 2)
186
+ }.to_h
187
+ end
106
188
  end
107
189
 
108
- def dat_url
109
- @board.dat_url(@id)
190
+ class ThreadBase
191
+ private_class_method :new
192
+ attr_reader :board, :id, :title, :last
193
+
194
+ def initialize(board, id, title, last)
195
+ @board = board
196
+ @id = id
197
+ @title = title
198
+ @last = last
199
+ end
200
+
201
+ def dat_url
202
+ @board.dat_url(@id)
203
+ end
204
+
110
205
  end
111
206
 
112
- def posts(range)
113
- fail ArgumentError unless range.is_a? Range
114
- dat_for_range(range).each_line.map do |line|
115
- Post.from_line(line.chomp).tap do |post|
116
- # ついでに last を更新
117
- @last = [post.no, last].max
207
+ module Shitaraba
208
+ SHITARABA_THREAD_URL_PATTERN = %r{\Ahttp://jbbs\.shitaraba\.net/bbs/read\.cgi/(\w+)/(\d+)/(\d+)(:?|\/.*)\z}
209
+ SHITARABA_BOARD_TOP_URL_PATTERN = %r{\Ahttp://jbbs\.shitaraba\.net/(\w+)/(\d+)/?\z}
210
+
211
+ # したらば板
212
+ class Board < Bbs::BoardBase
213
+ class << self
214
+ def from_url(url)
215
+ if url.to_s =~ SHITARABA_BOARD_TOP_URL_PATTERN
216
+ category, board_num = $1, $2.to_i
217
+ return Board.send(:new, category, board_num)
218
+ elsif url.to_s =~ SHITARABA_THREAD_URL_PATTERN
219
+ category, board_num, thread_num = $1, $2.to_i, $3.to_i
220
+ return Board.send(:new, category, board_num)
221
+ else
222
+ return nil
223
+ end
224
+ end
225
+ end
226
+
227
+ def initialize(category, board_num)
228
+ super('EUC-JP')
229
+ @category = category
230
+ @board_num = board_num
231
+ @settings_url = URI.parse( "http://jbbs.shitaraba.net/bbs/api/setting.cgi/#{category}/#{board_num}/" )
232
+ @thread_list_url = URI.parse( "http://jbbs.shitaraba.net/#{category}/#{board_num}/subject.txt" )
233
+ end
234
+
235
+ def dat_url(thread_num)
236
+ return URI.parse("http://jbbs.shitaraba.net/bbs/rawmode.cgi/#{@category}/#{@board_num}/#{thread_num}/")
237
+ end
238
+
239
+ def create_thread_from_line(line)
240
+ Thread.from_line(line, self)
241
+ end
242
+ end
243
+
244
+ # したらばスレッド
245
+ class Thread < Bbs::ThreadBase
246
+ class << self
247
+ def from_url(url)
248
+ if url.to_s =~ SHITARABA_THREAD_URL_PATTERN
249
+ category, board_num, thread_num = $1, $2.to_i, $3.to_i
250
+ board = Board.send(:new, category, board_num)
251
+ thread = board.thread(thread_num)
252
+ raise 'no such thread' if thread.nil?
253
+ return thread
254
+ else
255
+ return nil
256
+ end
257
+ end
258
+
259
+ def from_line(line, board)
260
+ unless line =~ /^(\d+)\.cgi,(.+?)\((\d+)\)$/
261
+ fail 'スレ一覧のフォーマットが変です'
262
+ end
263
+ id, title, last = $1.to_i, $2, $3.to_i
264
+ Thread.send(:new, board, id, title, last)
265
+ end
266
+ end
267
+
268
+ def initialize(board, id, title, last = 1)
269
+ super
270
+ end
271
+
272
+ def posts(range)
273
+ fail ArgumentError unless range.is_a? Range
274
+ dat_for_range(range).each_line.map do |line|
275
+ post = create_post(line.chomp)
276
+ @last = [post.no, last].max
277
+ post
278
+ end
279
+ end
280
+
281
+ private
282
+
283
+ def create_post(line)
284
+ no, name, mail, date, body, = line.split('<>', 6)
285
+ Post.new(no, name, mail, date, body)
286
+ end
287
+
288
+ def dat_for_range(range)
289
+ if range.last == Float::INFINITY
290
+ query = "#{range.first}-"
291
+ else
292
+ query = "#{range.first}-#{range.last}"
293
+ end
294
+ url = URI(dat_url + query)
295
+ @board.send(:download_text, url)
296
+ end
297
+ end
298
+ end # Shitaraba
299
+
300
+ module Nichan
301
+ # 2ちゃん板
302
+ class Board < Bbs::BoardBase
303
+ class << self
304
+ def from_url(url)
305
+ uri = URI.parse(url)
306
+ board_name = uri.path.split('/').reject(&:empty?).first
307
+ raise 'bad url' if board_name.nil?
308
+ Board.send(:new, uri.hostname, uri.port, board_name)
309
+ end
310
+ end
311
+
312
+ def initialize(hostname, port, name)
313
+ super('CP932')
314
+ @hostname, @port, @name = hostname, port, name
315
+
316
+ @settings_url = URI.parse("http://#{hostname}:#{port}/#{name}/SETTING.TXT")
317
+ @thread_list_url = URI.parse("http://#{hostname}:#{port}/#{name}/subject.txt")
318
+ end
319
+
320
+ def dat_url(thread_num)
321
+ "http://#{@hostname}:#{@port}/#{@name}/dat/#{thread_num}.dat"
322
+ end
323
+
324
+ def create_thread_from_line(line)
325
+ Thread.from_line(line, self)
326
+ end
327
+ end
328
+
329
+ NICHAN_THREAD_URL_PATTERN = %r{\Ahttp://[a-zA-z\-\.]+/test/read\.cgi\/(\w+)/(\d+)($|/)}
330
+
331
+ # 2ちゃんスレッド
332
+ class Thread < ThreadBase
333
+ class << self
334
+ def from_url(url)
335
+ if url.to_s =~ NICHAN_THREAD_URL_PATTERN
336
+ board_name, thread_num = $1, $2.to_i
337
+ uri = URI(url)
338
+ board = Board.send(:new, uri.hostname, uri.port, board_name)
339
+ thread = board.thread(thread_num)
340
+ raise 'no such thread' if thread.nil?
341
+ return thread
342
+ else
343
+ raise 'bad URL'
344
+ end
345
+ end
346
+
347
+ def from_line(line, board)
348
+ unless line =~ /^(\d+)\.dat<>(.+?) \((\d+)\)$/
349
+ fail 'スレ一覧のフォーマットが変です'
350
+ end
351
+ id, title, last = $1.to_i, $2, $3.to_i
352
+ Thread.send(:new, board, id, title, last)
353
+ end
354
+ end
355
+
356
+ def initialize(board, id, title, last = 1)
357
+ super
118
358
  end
359
+
360
+ def posts(range)
361
+ fail ArgumentError unless range.is_a? Range
362
+ url = URI(dat_url)
363
+ lines = @board.send(:download_text, url)
364
+ ary = []
365
+ lines.each_line.with_index(1) do |line, res_no|
366
+ next unless range.include?(res_no)
367
+
368
+ name, mail, date, body, title = line.chomp.split('<>', 5)
369
+ post = Post.new(res_no.to_s, name, mail, date, body)
370
+ ary << post
371
+ @last = [post.no, last].max
372
+ end
373
+ return ary
374
+ end
375
+
119
376
  end
377
+
120
378
  end
121
379
 
122
- def dat_for_range(range)
123
- if range.last == Float::INFINITY
124
- query = "#{range.first}-"
125
- else
126
- query = "#{range.first}-#{range.last}"
380
+ # Bbs.create_board(url) → Shitaraba::Board | Nichan::Board
381
+ # Bbs.create_thread(url) Shitaraba::Thread | Nichan::Thread
382
+
383
+ BOARD_CLASSES = [Shitaraba::Board, Nichan::Board].freeze
384
+ THREAD_CLASSES = [Shitaraba::Thread, Nichan::Thread].freeze
385
+
386
+ if $DEBUG
387
+ unless BOARD_CLASSES.all? { |k| k.respond_to?(:from_url) }
388
+ raise 'unmet assumption'
389
+ end
390
+
391
+ unless THREAD_CLASSES.all? { |k| k.respond_to?(:from_url) and k.respond_to?(:from_line) }
392
+ raise 'unmet assumption'
127
393
  end
128
- url = URI(dat_url + query)
129
- @board.ダウンロード(url).force_encoding("EUC-JP").encode("UTF-8")
130
394
  end
131
- end
132
395
 
133
- end # Module
134
- # include Bbs
135
- # 自板 = C板.new("game", 48538)
136
- # # puts 自板.設定
137
- # # puts 自板.スレ一覧
138
- # t = 自板.thread(1416739363)
396
+ def create_board(url)
397
+ BOARD_CLASSES.each do |klass|
398
+ board = klass.from_url(url)
399
+ return board if board
400
+ end
401
+ return nil
402
+ end
403
+ module_function :create_board
139
404
 
140
- # p t.posts(900..950)
405
+ def create_thread(url)
406
+ THREAD_CLASSES.each do |klass|
407
+ thread = klass.from_url(url)
408
+ return thread if thread
409
+ end
410
+ return nil
411
+ end
412
+ module_function :create_thread
141
413
 
414
+ end # Bbs
@@ -67,10 +67,18 @@ class Executable
67
67
  end
68
68
  end
69
69
 
70
+ def get_board_settings(board)
71
+ return board.settings
72
+ rescue Bbs::Downloader::DownloadFailure => e
73
+ STDERR.puts "Warning: 以下の場所から掲示板の設定が取得できませんでした。(#{e.response.message})"
74
+ STDERR.puts board.settings_url
75
+ return {'BBS_TITLE'=>'<不明>'}
76
+ end
77
+
70
78
  def start_polling(thread, start_no)
71
79
  out = LineIndicator.new
72
80
  delay = @settings.current['delay_seconds']
73
- board_settings = thread.board.設定
81
+ board_settings = get_board_settings(thread.board)
74
82
  thread_stop = (board_settings['BBS_THREAD_STOP'] || '1000').to_i
75
83
 
76
84
  puts "#{board_settings['BBS_TITLE']} − #{thread.title}(#{thread.last})"
@@ -104,7 +112,9 @@ class Executable
104
112
  rescue Interrupt
105
113
  STDERR.puts "\nユーザー割り込みにより停止"
106
114
  rescue => e
107
- STDERR.puts "error occured #{e.message}"
115
+ STDERR.puts "error occured"
116
+ puts e.message
117
+ puts e.backtrace
108
118
  STDERR.puts "retrying..., ^C to quit"
109
119
  sleep 3
110
120
  start_polling(thread, start_no)
@@ -129,24 +139,20 @@ EOD
129
139
  raise UsageError
130
140
  elsif ARGV.size < 1
131
141
  url = @settings.current['thread_url']
142
+ thread = Bbs::create_thread(url)
132
143
  else
133
144
  url = ARGV[0]
134
145
 
135
- if url =~ %r{\Ah?ttp://jbbs.shitaraba.net/bbs/read.cgi/(\w+)/(\d+)/(\d+)/?\z}
146
+ begin
147
+ thread = Bbs::create_thread(url)
136
148
  @settings.current['thread_url'] = url
137
- else
149
+ rescue
138
150
  puts "URLが変です"
139
151
  usage
140
152
  exit 1
141
153
  end
142
154
  end
143
155
 
144
- if url =~ %r{\Ah?ttp://jbbs.shitaraba.net/bbs/read.cgi/(\w+)/(\d+)/(\d+)/?\z}
145
- ita = [$1, $2.to_i]
146
- sure = $3.to_i
147
- end
148
-
149
- thread = Bbs::C板.new(*ita).thread(sure)
150
156
  start_no = ARGV[1] ? ARGV[1].to_i : thread.last + 1
151
157
  start_polling(thread, start_no)
152
158
  rescue UsageError
@@ -23,24 +23,6 @@ def render_resno(no)
23
23
  no.to_s
24
24
  end
25
25
 
26
- def render_date(t)
27
- weekday = [*'日月火水木金土'.each_char]
28
- delta = Time.now - t
29
-
30
- case delta
31
- when 0...1
32
- "たった今"
33
- when 1...60
34
- "#{delta.to_i}秒前"
35
- when 60...3600
36
- "#{(delta / 60).to_i}分前"
37
- when 3600...(24 * 3600)
38
- "#{(delta / 3600).to_i}時間前"
39
- else
40
- "%d/%d/%d(%s) %02d:%02d:%02d" % [t.year, t.month, t.day, weekday[t.wday], t.hour, t.min, t.sec]
41
- end
42
- end
43
-
44
26
  def indent(n, text)
45
27
  text.each_line.map { |line| n.en + line }.join
46
28
  end
@@ -51,7 +33,7 @@ def render_body(body)
51
33
  end
52
34
 
53
35
  def render_post(post)
54
- "#{render_resno post.no}:#{render_name post.name, post.mail}:#{render_date post.date}\n" \
36
+ "#{render_resno post.no}:#{render_name post.name, post.mail}:#{post.date}\n" \
55
37
  "#{render_body post.body}"
56
38
  end
57
39
 
data/lib/bbiff/show.rb CHANGED
@@ -16,7 +16,7 @@ class Show
16
16
  end
17
17
 
18
18
  title = ARGV[0]
19
- post = Bbs::Post.from_line(ARGV[1])
19
+ post = Bbs::Post.from_s(ARGV[1])
20
20
  notify_send = ENV['BBIFF_NOTIFY_SEND'] ||
21
21
  (`which #{NOTIFY_SEND}` != "" ? NOTIFY_SEND : 'echo')
22
22
  system("#{notify_send} #{Shellwords.escape(title)} #{Shellwords.escape(render_post(post))}")
data/lib/bbiff/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Bbiff
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bbiff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoteichi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-02 00:00:00.000000000 Z
11
+ date: 2016-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler