bbiff 0.2.2 → 0.3.0

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 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