bbiff 0.1.3 → 0.2.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 +4 -4
- data/README.md +11 -0
- data/bbiff.gemspec +3 -0
- data/bin/bbiff +1 -1
- data/bin/bbiff-show +5 -0
- data/lib/bbiff.rb +3 -61
- data/lib/bbiff/bbs_reader.rb +19 -3
- data/lib/bbiff/executable.rb +155 -0
- data/lib/bbiff/settings.rb +47 -0
- data/lib/bbiff/show.rb +31 -0
- data/lib/bbiff/version.rb +1 -1
- metadata +35 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c1a06f19c088ba3f97fb5f001619c04457be919
|
4
|
+
data.tar.gz: 1ddafb3e022314b5faf792730855f8c208987199
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 212dd524640a9dfbf8882ff9f91866f8c2953de159047226dd163815acc8b0d821c76a3c57dbb46caa2da503d54b6ef508b605280b422794adefc32d79b75927
|
7
|
+
data.tar.gz: a08cbd2ebed22e3504a5a03f3a2c13f3d14485e86147aedc0bd2a24e9585076e45da12ef69810ac5cdfc10f39dc0e50a72705827be0e27f568f3276a792f110c
|
data/README.md
CHANGED
@@ -17,6 +17,12 @@ notify-send コマンド
|
|
17
17
|
スレッドのURLは http://jbbs.shitaraba.net/bbs/read.cgi/カテゴリ/板ID/スレID/
|
18
18
|
の形式です。
|
19
19
|
|
20
|
+
単に
|
21
|
+
|
22
|
+
bbiff
|
23
|
+
|
24
|
+
とすると、前回監視したスレッドを監視します。
|
25
|
+
|
20
26
|
## 開発・TODO
|
21
27
|
|
22
28
|
- .travis.ymlでテストするなら要編集
|
@@ -34,6 +40,11 @@ ver 0.1.2
|
|
34
40
|
ver 0.1.3
|
35
41
|
* インストールすると動かなくなっていたバグを修正。
|
36
42
|
|
43
|
+
ver 0.2.0
|
44
|
+
* プログラムの動作状態を表示するようにした。
|
45
|
+
* 設定ファイルを ~/.config/bbiff 以下に置くようにした。
|
46
|
+
* 最後に監視したスレッドを覚えておいて、URLを省略した時のデフォルト
|
47
|
+
にするようにした。
|
37
48
|
|
38
49
|
## 作者
|
39
50
|
|
data/bbiff.gemspec
CHANGED
@@ -15,10 +15,13 @@ 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'
|
18
19
|
spec.require_paths = ["lib"]
|
19
20
|
|
20
21
|
spec.add_development_dependency "bundler", "~> 1.10"
|
21
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
22
23
|
spec.add_development_dependency "rspec"
|
23
24
|
spec.add_dependency "activesupport", "~> 4.0"
|
25
|
+
spec.add_dependency "unicode-display_width"
|
26
|
+
spec.add_dependency "toml-rb"
|
24
27
|
end
|
data/bin/bbiff
CHANGED
data/bin/bbiff-show
ADDED
data/lib/bbiff.rb
CHANGED
@@ -2,64 +2,6 @@ require 'shellwords'
|
|
2
2
|
require_relative 'bbiff/version'
|
3
3
|
require_relative 'bbiff/bbs_reader'
|
4
4
|
require_relative 'bbiff/res_format'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
1..Float::INFINITY
|
9
|
-
elsif str =~ /^\d+$/
|
10
|
-
str.to_i..str.to_i
|
11
|
-
elsif str =~ /^\d+-$/
|
12
|
-
str.to_i..Float::INFINITY
|
13
|
-
elsif str =~ /^(\d+)-(\d+)$/
|
14
|
-
$1.to_i..$2.to_i
|
15
|
-
else
|
16
|
-
fail ArgumentError
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def start_polling(thread, start_no)
|
21
|
-
default_notify_command = 'notify-send'
|
22
|
-
notify_send = ENV['BBIFF_NOTIFY_SEND'] || (system("which #{default_notify_command}") ? default_notify_command : 'echo')
|
23
|
-
loop do
|
24
|
-
thread.posts(parse_range("#{start_no}-")).each do |post|
|
25
|
-
system("#{notify_send} #{Shellwords.escape(render_post(post))}")
|
26
|
-
sleep 1
|
27
|
-
end
|
28
|
-
start_no = thread.last + 1
|
29
|
-
break if start_no >= 1000
|
30
|
-
sleep 10
|
31
|
-
end
|
32
|
-
rescue Interrupt
|
33
|
-
rescue => e
|
34
|
-
STDERR.puts "error occured #{e.message}"
|
35
|
-
STDERR.puts "retrying..., ^C to quit"
|
36
|
-
sleep 3
|
37
|
-
start_polling(thread, start_no)
|
38
|
-
end
|
39
|
-
|
40
|
-
def usage
|
41
|
-
STDERR.puts "Usage: bbiff [http://jbbs.shitaraba.net/bbs/read.cgi/CATEGORY/BOARD_ID/THREAD_ID/] [START_NUMBER]"
|
42
|
-
|
43
|
-
STDERR.puts <<"EOD"
|
44
|
-
|
45
|
-
Bbiff version #{Bbiff::VERSION}
|
46
|
-
Copyright © 2016 Yoteichi
|
47
|
-
EOD
|
48
|
-
end
|
49
|
-
|
50
|
-
def main
|
51
|
-
unless ARGV.size >= 1
|
52
|
-
usage
|
53
|
-
exit 1
|
54
|
-
end
|
55
|
-
url = ARGV[0]
|
56
|
-
|
57
|
-
if url =~ %r{\Ah?ttp://jbbs.shitaraba.net/bbs/read.cgi/(\w+)/(\d+)/(\d+)/?\z}
|
58
|
-
ita = [$1, $2.to_i]
|
59
|
-
sure = $3.to_i
|
60
|
-
end
|
61
|
-
|
62
|
-
thread = Bbs::C板.new(*ita).thread(sure)
|
63
|
-
start_no = ARGV[1] ? ARGV[1].to_i : thread.last + 1
|
64
|
-
start_polling(thread, start_no)
|
65
|
-
end
|
5
|
+
require_relative 'bbiff/settings'
|
6
|
+
require_relative 'bbiff/executable'
|
7
|
+
require_relative 'bbiff/show'
|
data/lib/bbiff/bbs_reader.rb
CHANGED
@@ -20,7 +20,7 @@ class C板
|
|
20
20
|
http.get(@設定URL.path)
|
21
21
|
}
|
22
22
|
r = 応答.body
|
23
|
-
return r.force_encoding("EUC-JP").encode("UTF-8")
|
23
|
+
return 設定をパーズする(r.force_encoding("EUC-JP").encode("UTF-8"))
|
24
24
|
end
|
25
25
|
|
26
26
|
def スレ一覧
|
@@ -52,10 +52,18 @@ class C板
|
|
52
52
|
Thread.new(self, id, title, last)
|
53
53
|
end
|
54
54
|
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def 設定をパーズする(文字列)
|
59
|
+
文字列.each_line.map { |line|
|
60
|
+
line.chomp.split(/=/, 2)
|
61
|
+
}.to_h
|
62
|
+
end
|
55
63
|
end
|
56
64
|
|
57
65
|
class Post
|
58
|
-
attr_reader :no, :name, :mail, :
|
66
|
+
attr_reader :no, :name, :mail, :body
|
59
67
|
|
60
68
|
def self.from_line(line)
|
61
69
|
no, name, mail, date, body, = line.split('<>')
|
@@ -66,10 +74,18 @@ class Post
|
|
66
74
|
@no = no.to_i
|
67
75
|
@name = name
|
68
76
|
@mail = mail
|
69
|
-
@date =
|
77
|
+
@date = date
|
70
78
|
@body = body
|
71
79
|
end
|
72
80
|
|
81
|
+
def date
|
82
|
+
str2time(@date)
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_s
|
86
|
+
[no, name, mail, @date, body].join('<>')
|
87
|
+
end
|
88
|
+
|
73
89
|
private
|
74
90
|
|
75
91
|
def str2time(str)
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'unicode/display_width'
|
2
|
+
|
3
|
+
module Bbiff
|
4
|
+
|
5
|
+
class Executable
|
6
|
+
class LineIndicator
|
7
|
+
def initialize(out = STDOUT)
|
8
|
+
@width = 0
|
9
|
+
@out = out
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_line(str)
|
13
|
+
clear
|
14
|
+
if str[-1] == "\n"
|
15
|
+
if str.rindex("\n") != str.size-1 || str.index("\n") < str.rindex("\n")
|
16
|
+
raise 'multiline'
|
17
|
+
end
|
18
|
+
|
19
|
+
@out.print str
|
20
|
+
@width = 0
|
21
|
+
else
|
22
|
+
@out.print str
|
23
|
+
@width = mbswidth(str)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def newline
|
28
|
+
@out.print "\n"
|
29
|
+
@width = 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def clear
|
33
|
+
@out.print "\r#{' ' * @width}\r"
|
34
|
+
@width = 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def puts(str)
|
38
|
+
set_line(str)
|
39
|
+
newline
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def mbswidth(str)
|
45
|
+
Unicode::DisplayWidth.of(str)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize
|
50
|
+
@settings = Settings.new
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_range(str)
|
54
|
+
if str == "all"
|
55
|
+
1..Float::INFINITY
|
56
|
+
elsif str =~ /^\d+$/
|
57
|
+
str.to_i..str.to_i
|
58
|
+
elsif str =~ /^\d+-$/
|
59
|
+
str.to_i..Float::INFINITY
|
60
|
+
elsif str =~ /^(\d+)-(\d+)$/
|
61
|
+
$1.to_i..$2.to_i
|
62
|
+
else
|
63
|
+
fail ArgumentError
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def start_polling(thread, start_no)
|
68
|
+
out = LineIndicator.new
|
69
|
+
delay = @settings.current['delay_seconds']
|
70
|
+
board_settings = thread.board.設定
|
71
|
+
thread_stop = (board_settings['BBS_THREAD_STOP'] || '1000').to_i
|
72
|
+
|
73
|
+
puts "#{board_settings['BBS_TITLE']} − #{thread.title}(#{thread.last})"
|
74
|
+
puts " #{@settings.current['thread_url']}"
|
75
|
+
|
76
|
+
loop do
|
77
|
+
out.set_line "#{thread.title}(#{thread.last}) 新着レス確認中"
|
78
|
+
|
79
|
+
thread.posts(parse_range("#{start_no}-")).each do |post|
|
80
|
+
out.puts "-----"
|
81
|
+
puts render_post(post)
|
82
|
+
|
83
|
+
system(@settings.current['bbiff_show'],
|
84
|
+
thread.title, post.to_s)
|
85
|
+
|
86
|
+
sleep 1
|
87
|
+
end
|
88
|
+
|
89
|
+
start_no = thread.last + 1
|
90
|
+
if start_no >= thread_stop
|
91
|
+
out.puts "スレッドストップ"
|
92
|
+
break
|
93
|
+
end
|
94
|
+
|
95
|
+
delay.times do |i|
|
96
|
+
j = i + 1
|
97
|
+
out.set_line "#{thread.title}(#{thread.last}) 待機中 [#{'.'*j}#{' '*(delay - j)}]"
|
98
|
+
sleep 1
|
99
|
+
end
|
100
|
+
end
|
101
|
+
rescue Interrupt
|
102
|
+
STDERR.puts "\nユーザー割り込みにより停止"
|
103
|
+
rescue => e
|
104
|
+
STDERR.puts "error occured #{e.message}"
|
105
|
+
STDERR.puts "retrying..., ^C to quit"
|
106
|
+
sleep 3
|
107
|
+
start_polling(thread, start_no)
|
108
|
+
end
|
109
|
+
|
110
|
+
def usage
|
111
|
+
STDERR.puts "Usage: bbiff [http://jbbs.shitaraba.net/bbs/read.cgi/CATEGORY/BOARD_ID/THREAD_ID/] [START_NUMBER]"
|
112
|
+
|
113
|
+
STDERR.puts <<"EOD"
|
114
|
+
|
115
|
+
Bbiff version #{Bbiff::VERSION}
|
116
|
+
Copyright © 2016 Yoteichi
|
117
|
+
EOD
|
118
|
+
end
|
119
|
+
|
120
|
+
def main
|
121
|
+
if ARGV.include?('-h') || ARGV.include?('--help')
|
122
|
+
usage
|
123
|
+
exit 1
|
124
|
+
end
|
125
|
+
|
126
|
+
if ARGV.size < 1 && !@settings.current['thread_url']
|
127
|
+
raise UsageError
|
128
|
+
elsif ARGV.size < 1
|
129
|
+
url = @settings.current['thread_url']
|
130
|
+
else
|
131
|
+
url = ARGV[0]
|
132
|
+
|
133
|
+
if url =~ %r{\Ah?ttp://jbbs.shitaraba.net/bbs/read.cgi/(\w+)/(\d+)/(\d+)/?\z}
|
134
|
+
@settings.current['thread_url'] = url
|
135
|
+
else
|
136
|
+
puts "URLが変です"
|
137
|
+
usage
|
138
|
+
exit 1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
if url =~ %r{\Ah?ttp://jbbs.shitaraba.net/bbs/read.cgi/(\w+)/(\d+)/(\d+)/?\z}
|
143
|
+
ita = [$1, $2.to_i]
|
144
|
+
sure = $3.to_i
|
145
|
+
end
|
146
|
+
|
147
|
+
thread = Bbs::C板.new(*ita).thread(sure)
|
148
|
+
start_no = ARGV[1] ? ARGV[1].to_i : thread.last + 1
|
149
|
+
start_polling(thread, start_no)
|
150
|
+
ensure
|
151
|
+
@settings.save
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'toml'
|
3
|
+
|
4
|
+
module Bbiff
|
5
|
+
|
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
|
27
|
+
|
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))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
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/show.rb
ADDED
@@ -0,0 +1,31 @@
|
|
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_line(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
|
+
|
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.2.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-
|
11
|
+
date: 2016-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,11 +66,40 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '4.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: unicode-display_width
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: toml-rb
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
69
97
|
description:
|
70
98
|
email:
|
71
99
|
- plonk@piano.email.ne.jp
|
72
100
|
executables:
|
73
101
|
- bbiff
|
102
|
+
- bbiff-show
|
74
103
|
extensions: []
|
75
104
|
extra_rdoc_files: []
|
76
105
|
files:
|
@@ -83,9 +112,13 @@ files:
|
|
83
112
|
- Rakefile
|
84
113
|
- bbiff.gemspec
|
85
114
|
- bin/bbiff
|
115
|
+
- bin/bbiff-show
|
86
116
|
- lib/bbiff.rb
|
87
117
|
- lib/bbiff/bbs_reader.rb
|
118
|
+
- lib/bbiff/executable.rb
|
88
119
|
- lib/bbiff/res_format.rb
|
120
|
+
- lib/bbiff/settings.rb
|
121
|
+
- lib/bbiff/show.rb
|
89
122
|
- lib/bbiff/version.rb
|
90
123
|
homepage: https://github.com/plonk/bbiff
|
91
124
|
licenses:
|