bbiff 0.3.5 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -6
- data/bbiff.gemspec +0 -2
- data/lib/bbiff.rb +0 -1
- data/lib/bbiff/bbs_reader.rb +24 -12
- data/lib/bbiff/executable.rb +55 -21
- data/lib/bbiff/settings.rb +9 -40
- data/lib/bbiff/version.rb +1 -1
- metadata +2 -19
- data/bin/bbiff-show +0 -5
- data/lib/bbiff/show.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4758c8dd5e687a8cafc4950aff149891315912f57c9c6089d411ca40f64af251
|
4
|
+
data.tar.gz: 05201ef427ddafaa0d8319d32da510afdd26363463961b8f70ee115d983a7e0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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>
|
data/bbiff.gemspec
CHANGED
@@ -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
|
data/lib/bbiff.rb
CHANGED
data/lib/bbiff/bbs_reader.rb
CHANGED
@@ -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
|
-
|
89
|
-
|
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
|
-
|
121
|
-
|
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://[
|
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 = $
|
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,
|
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
|
-
|
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
|
data/lib/bbiff/executable.rb
CHANGED
@@ -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}-")
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
thread.title, post.to_s)
|
127
|
+
unless @settings.current['no_render']
|
128
|
+
puts render_post(post)
|
129
|
+
end
|
123
130
|
|
124
|
-
|
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.
|
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}#{' '*(
|
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
|
-
|
165
|
-
|
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
|
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 =
|
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 =
|
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
|
|
data/lib/bbiff/settings.rb
CHANGED
@@ -1,47 +1,16 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'toml'
|
3
|
-
|
4
1
|
module Bbiff
|
5
2
|
|
6
|
-
class Settings
|
7
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
data/lib/bbiff/version.rb
CHANGED
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.
|
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-
|
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:
|
data/bin/bbiff-show
DELETED
data/lib/bbiff/show.rb
DELETED
@@ -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
|
-
|