bbiff 0.3.5 → 0.4.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
  SHA256:
3
- metadata.gz: 390245509f3595fee671a77bca02daf4592e2747cd01543de817ae804b509122
4
- data.tar.gz: 3fb134823404b0ce3e93b01ada05e7d1dbd152bfb193e01c1931e3b5ce1afc51
3
+ metadata.gz: 4758c8dd5e687a8cafc4950aff149891315912f57c9c6089d411ca40f64af251
4
+ data.tar.gz: 05201ef427ddafaa0d8319d32da510afdd26363463961b8f70ee115d983a7e0f
5
5
  SHA512:
6
- metadata.gz: 5f1cac9cfc598df67c23fbeaf572f824b2fa775693ccb4d5e99f6ab875edc6843acb3314450bfad11262cf14555616aa8e147d66361e719def0102c431c385b4
7
- data.tar.gz: a499ad13b6f5616df60bfc456373f28705164d1fb1f547c8492f8eac7038c38ec728c06e574071e5a011cc24b46e1a63eebb4fda67a787eec04b343a2635eb04
6
+ metadata.gz: cdb83ce8f345ffedb08e7778f1498aa22cf23e317266b77befb643fbeefe3d470f6c289704a0674e308516f1064513ea8f4410d54012240419b6f56cccb76c63
7
+ data.tar.gz: f3cab0dd96adc6d675491aac3bf2978148474ba8d94680f31422e902db360533e43790da75358d1401e40166069337a1fa0cf62af258ef14429b60363ef61b60
data/README.md CHANGED
@@ -7,6 +7,10 @@
7
7
 
8
8
  sudo apt-get install libnotify-bin
9
9
 
10
+ `BBIFF_NOTIFY_SEND` 環境変数をセットすることで、notify-send 以外のコマ
11
+ ンドをレスの通知に使うこともできます。1つ目の引数にはスレッドタイトル
12
+ が、2つ目の引数には投稿の内容が渡されます。
13
+
10
14
  ## インストール
11
15
 
12
16
  `gem install bbiff` でインストールできます。
@@ -20,12 +24,6 @@
20
24
  んねる互換掲示板の場合は、`http://ホスト名/test/read.cgi/板名/スレID/`
21
25
  のような形式になります。
22
26
 
23
- 単に
24
-
25
- bbiff
26
-
27
- とすると、前回監視したスレッドを監視します。
28
-
29
27
  ## リリース
30
28
 
31
29
  ver 0.1.0
@@ -68,6 +66,14 @@ ver 0.3.3
68
66
  ver 0.3.4
69
67
  * 通知でレスの最後に <><> が表示されるのを修正。
70
68
 
69
+ ver 0.3.5
70
+ * httpsなしたらば掲示板のURLが使えるようにした。
71
+
72
+ ver 0.4.0
73
+ * ロングポーリングに対応。(--long-pollingオプション)
74
+ * スタンドアローンなレンダリングの抑制。(--no-renderオプション)
75
+ * 設定ファイル(~/.config/bbiff/settings.tml)を廃止した。
76
+
71
77
  ## 作者
72
78
 
73
79
  予定地 <plonk@piano.email.ne.jp>
@@ -15,12 +15,10 @@ Gem::Specification.new do |spec|
15
15
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
16
  spec.bindir = "bin"
17
17
  spec.executables << 'bbiff'
18
- spec.executables << 'bbiff-show'
19
18
  spec.require_paths = ["lib"]
20
19
 
21
20
  spec.add_development_dependency "bundler", "~> 1.10"
22
21
  spec.add_development_dependency "rake", "~> 10.0"
23
22
  spec.add_development_dependency "rspec"
24
23
  spec.add_dependency "unicode-display_width", "~>1.4.1"
25
- spec.add_dependency "toml-rb", "~>0.3.12"
26
24
  end
@@ -4,4 +4,3 @@ require_relative 'bbiff/bbs_reader'
4
4
  require_relative 'bbiff/res_format'
5
5
  require_relative 'bbiff/settings'
6
6
  require_relative 'bbiff/executable'
7
- require_relative 'bbiff/show'
@@ -1,12 +1,14 @@
1
1
  require 'net/http'
2
2
  require 'uri'
3
- require 'pp' if $DEBUG
4
3
 
5
4
  module Bbs
6
5
 
7
6
  class NotFoundError < StandardError
8
7
  end
9
8
 
9
+ class FormatError < StandardError
10
+ end
11
+
10
12
  class Post
11
13
  class << self
12
14
  def from_s(str)
@@ -79,14 +81,15 @@ module Bbs
79
81
  # ASCII-8BIT エンコーディングの文字列を返す。
80
82
  def download_binary(uri)
81
83
  resource = @resource_cache[uri]
82
- if resource
84
+ if resource && resource.data.size > 0
85
+
83
86
  Net::HTTP.start(uri.host, uri.port) do |http|
84
87
  request = Net::HTTP::Get.new(uri)
85
88
  request['range'] = "bytes=#{resource.data.bytesize}-"
86
89
  response = http.request(request)
87
90
  response.body.force_encoding('ASCII-8BIT')
88
- pp response.code if $DEBUG
89
- pp response.to_hash if $DEBUG
91
+ p response.code if $DEBUG
92
+ p response.to_hash if $DEBUG
90
93
  case response
91
94
  when Net::HTTPPartialContent
92
95
  p :partial if $DEBUG
@@ -117,8 +120,8 @@ module Bbs
117
120
  request = Net::HTTP::Get.new(uri)
118
121
  response = http.request(request)
119
122
  response.body.force_encoding('ASCII-8BIT')
120
- pp response.code if $DEBUG
121
- pp response.to_hash if $DEBUG
123
+ p response.code if $DEBUG
124
+ p response.to_hash if $DEBUG
122
125
  case response
123
126
  when Net::HTTPOK
124
127
  else
@@ -272,7 +275,7 @@ module Bbs
272
275
  super
273
276
  end
274
277
 
275
- def posts(range)
278
+ def posts(range, opts = {})
276
279
  fail ArgumentError unless range.is_a? Range
277
280
  dat_for_range(range).each_line.map do |line|
278
281
  post = create_post(line.chomp)
@@ -329,14 +332,14 @@ module Bbs
329
332
  end
330
333
  end
331
334
 
332
- NICHAN_THREAD_URL_PATTERN = %r{\Ahttp://[a-zA-z\-\.]+(?::\d+)/test/read\.cgi\/(\w+)/(\d+)($|/)}
335
+ NICHAN_THREAD_URL_PATTERN = %r{\Ahttp://[0-9a-zA-z\-\.]+(:\d+)?/test/read\.cgi\/(\w+)/(\d+)($|/)}
333
336
 
334
337
  # 2ちゃんスレッド
335
338
  class Thread < ThreadBase
336
339
  class << self
337
340
  def from_url(url)
338
341
  if url.to_s =~ NICHAN_THREAD_URL_PATTERN
339
- board_name, thread_num = $1, $2.to_i
342
+ board_name, thread_num = $2, $3.to_i
340
343
  uri = URI(url)
341
344
  board = Board.send(:new, uri.hostname, uri.port, board_name)
342
345
  thread = board.thread(thread_num)
@@ -360,15 +363,24 @@ module Bbs
360
363
  super
361
364
  end
362
365
 
363
- def posts(range)
366
+ def posts(range, opts = {})
364
367
  fail ArgumentError unless range.is_a? Range
365
368
  url = URI(dat_url)
366
- lines = @board.send(:download_text, url)
369
+ lines = @board.send(:download_text,
370
+ if opts[:long_polling] then
371
+ url + "?long_polling=1"
372
+ else
373
+ url
374
+ end)
367
375
  ary = []
368
376
  lines.each_line.with_index(1) do |line, res_no|
369
377
  next unless range.include?(res_no)
370
378
 
371
- name, mail, date, body, title = line.chomp.split('<>', 5)
379
+ fields = line.chomp.split('<>', 5)
380
+ if fields.size != 5
381
+ raise FormatError, "invalid line #{line.inspect}"
382
+ end
383
+ name, mail, date, body, title = fields
372
384
  post = Post.new(res_no.to_s, name, mail, date, body)
373
385
  ary << post
374
386
  @last = [post.no, last].max
@@ -19,7 +19,7 @@ class Executable
19
19
  clear
20
20
  if str[-1] == "\n"
21
21
  if str.rindex("\n") != str.size-1 || str.index("\n") < str.rindex("\n")
22
- raise 'multiline'
22
+ raise 'multiline'
23
23
  end
24
24
 
25
25
  @out.print str
@@ -99,6 +99,11 @@ class Executable
99
99
  return {'BBS_TITLE'=>'<不明>'}
100
100
  end
101
101
 
102
+ def show(title, post)
103
+ notify_send = ENV['BBIFF_NOTIFY_SEND'] || (`which notify-send` != "" ? 'notify-send' : 'echo')
104
+ system("#{notify_send} #{Shellwords.escape(title)} #{Shellwords.escape(render_post(post))}")
105
+ end
106
+
102
107
  RETRY_INTERVAL_SECONDS = 3
103
108
 
104
109
  def start_polling(thread, start_no)
@@ -114,25 +119,28 @@ class Executable
114
119
  loop do
115
120
  out.set_line "#{thread.title}(#{thread.last}) 新着レス確認中"
116
121
 
117
- thread.posts(parse_range("#{start_no}-")).each do |post|
122
+ posts = thread.posts(parse_range("#{start_no}-"),
123
+ { long_polling: @settings.current['long_polling'] })
124
+ t = Time.now
125
+ posts.each do |post|
118
126
  out.puts "-----"
119
- puts render_post(post)
120
-
121
- system(@settings.current['bbiff_show'],
122
- thread.title, post.to_s)
127
+ unless @settings.current['no_render']
128
+ puts render_post(post)
129
+ end
123
130
 
124
- sleep 1
131
+ show(thread.title, post)
125
132
  end
126
133
 
127
134
  start_no = thread.last + 1
128
135
  if start_no > thread_stop
129
136
  out.puts "スレッドストップ"
130
- break
137
+ break
131
138
  end
132
139
 
133
- delay.times do |i|
140
+ d = [delay-(Time.now-t), 0].max.round
141
+ d.times do |i|
134
142
  j = i + 1
135
- out.set_line "#{thread.title}(#{thread.last}) 待機中 [#{'.'*j}#{' '*(delay - j)}]"
143
+ out.set_line "#{thread.title}(#{thread.last}) 待機中 [#{'.'*j}#{' '*(d - j)}]"
136
144
  sleep 1
137
145
  end
138
146
  end
@@ -147,30 +155,58 @@ class Executable
147
155
  STDERR.puts e.backtrace if $DEBUG
148
156
  STDERR.puts "#{RETRY_INTERVAL_SECONDS}秒後にリトライ"
149
157
  sleep RETRY_INTERVAL_SECONDS
158
+ thread = Bbs::create_thread(@settings.current['thread_url'])
150
159
  start_polling(thread, start_no)
151
160
  end
152
161
 
153
162
  def usage
154
- STDERR.puts "Usage: bbiff [http://jbbs.shitaraba.net/bbs/read.cgi/CATEGORY/BOARD_ID/THREAD_ID/] [START_NUMBER]"
155
-
163
+ STDERR.puts "Usage: bbiff [OPTIONS] [http://jbbs.shitaraba.net/bbs/read.cgi/CATEGORY/BOARD_ID/THREAD_ID/] [START_NUMBER]"
164
+
156
165
  STDERR.puts <<"EOD"
157
166
 
158
167
  Bbiff version #{Bbiff::VERSION}
159
168
  Copyright © 2016-2019 Yoteichi
169
+
170
+ -h, --help
171
+ --no-render
172
+ --debug
173
+ --long-polling (for Genkai)
174
+ --delay-seconds=N
160
175
  EOD
161
176
  end
162
177
 
163
178
  def main
164
- if ARGV.include?('-h') || ARGV.include?('--help')
165
- raise UsageError
179
+ args = []
180
+ ARGV.each do |arg|
181
+ case arg
182
+ when '-h', '--help'
183
+ raise UsageError
184
+ when '--no-render'
185
+ @settings.current['no_render'] = true
186
+ when '--debug'
187
+ $DEBUG = true
188
+ when '--long-polling'
189
+ @settings.current['long_polling'] = true
190
+ when /\A--delay-seconds=(.+)\z/
191
+ s = $1
192
+ if s =~ /\A\d+\z/
193
+ @settings.current['delay_seconds'] = s.to_i
194
+ else
195
+ STDERR.puts "delay-seconds must be a non-negative integer"
196
+ raise UsageError
197
+ end
198
+ when /\A-/
199
+ STDERR.puts "invalid option #{arg.inspect}"
200
+ raise UsageError
201
+ else
202
+ args << arg
203
+ end
166
204
  end
167
205
 
168
- if ARGV.size < 1 && !@settings.current['thread_url']
206
+ if args.size < 1
169
207
  raise UsageError
170
- elsif ARGV.size < 1
171
- url = @settings.current['thread_url']
172
208
  else
173
- url = ARGV[0]
209
+ url = args[0]
174
210
  end
175
211
 
176
212
  begin
@@ -188,13 +224,11 @@ EOD
188
224
  exit 1
189
225
  end
190
226
 
191
- start_no = ARGV[1] ? ARGV[1].to_i : thread.last + 1
227
+ start_no = args[1] ? args[1].to_i : thread.last + 1
192
228
  start_polling(thread, start_no)
193
229
  rescue UsageError
194
230
  usage
195
231
  exit 1
196
- ensure
197
- @settings.save
198
232
  end
199
233
  end
200
234
 
@@ -1,47 +1,16 @@
1
- require 'fileutils'
2
- require 'toml'
3
-
4
1
  module Bbiff
5
2
 
6
- class Settings
7
- attr_accessor :current
8
-
9
- APP_NAME = 'bbiff'
10
-
11
- def initialize
12
- @current = default.dup
13
- @config_dir = "#{ ENV['HOME'] }/.config/#{ APP_NAME }"
14
- load
15
- end
16
-
17
- def default
18
- { 'delay_seconds' => 10, 'bbiff_show' => 'bbiff-show' }
19
- end
20
-
21
- def load
22
- if File.readable?("#{@config_dir}/settings.tml")
23
- prefs = TOML.load_file("#{@config_dir}/settings.tml")
24
- self.current = current.merge(prefs)
25
- end
26
- end
3
+ class Settings
4
+ attr_accessor :current
27
5
 
28
- def save
29
- FileUtils.mkdir_p(@config_dir)
30
- prefs = (current.to_a - default.to_a).to_h
31
- File.open("#{@config_dir}/settings.tml", 'w') do |f|
32
- f.write(TOML.dump(prefs))
6
+ def initialize
7
+ @current = {
8
+ 'delay_seconds' => 7,
9
+ 'bbiff_show' => 'bbiff-show',
10
+ 'no_render' => false,
11
+ 'long_polling' => false,
12
+ }
33
13
  end
34
14
  end
35
15
 
36
16
  end
37
-
38
- end
39
-
40
- # settings = Bbiff::Settings.new
41
-
42
- # p settings.default
43
- # p settings.current
44
-
45
- # settings.current['delay_seconds'] = 7
46
- # settings.current['thread_url'] = 'http://jbbs.shitaraba.net/bbs/read.cgi/game/48538/1454983964'
47
- # settings.save
@@ -1,3 +1,3 @@
1
1
  module Bbiff
2
- VERSION = "0.3.5"
2
+ VERSION = "0.4.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.3.5
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoteichi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-05 00:00:00.000000000 Z
11
+ date: 2019-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,26 +66,11 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.4.1
69
- - !ruby/object:Gem::Dependency
70
- name: toml-rb
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 0.3.12
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 0.3.12
83
69
  description:
84
70
  email:
85
71
  - plonk@piano.email.ne.jp
86
72
  executables:
87
73
  - bbiff
88
- - bbiff-show
89
74
  extensions: []
90
75
  extra_rdoc_files: []
91
76
  files:
@@ -98,13 +83,11 @@ files:
98
83
  - Rakefile
99
84
  - bbiff.gemspec
100
85
  - bin/bbiff
101
- - bin/bbiff-show
102
86
  - lib/bbiff.rb
103
87
  - lib/bbiff/bbs_reader.rb
104
88
  - lib/bbiff/executable.rb
105
89
  - lib/bbiff/res_format.rb
106
90
  - lib/bbiff/settings.rb
107
- - lib/bbiff/show.rb
108
91
  - lib/bbiff/version.rb
109
92
  homepage: https://github.com/plonk/bbiff
110
93
  licenses:
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'bbiff'
4
-
5
- Bbiff::Show.new.main
@@ -1,31 +0,0 @@
1
- module Bbiff
2
-
3
- class Show
4
- class UsageError < StandardError
5
- end
6
-
7
- NOTIFY_SEND = 'notify-send'
8
-
9
- def usage
10
- STDERR.puts 'Usage: bbiff-show TITLE RES_LINE'
11
- end
12
-
13
- def main
14
- if ARGV.size != 2
15
- raise UsageError
16
- end
17
-
18
- title = ARGV[0]
19
- post = Bbs::Post.from_s(ARGV[1])
20
- notify_send = ENV['BBIFF_NOTIFY_SEND'] ||
21
- (`which #{NOTIFY_SEND}` != "" ? NOTIFY_SEND : 'echo')
22
- system("#{notify_send} #{Shellwords.escape(title)} #{Shellwords.escape(render_post(post))}")
23
-
24
- rescue UsageError
25
- usage
26
- end
27
-
28
- end
29
-
30
- end
31
-