simple2ch 0.1.8 → 1.1.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +25 -0
  4. data/.travis.yml +8 -0
  5. data/README.md +24 -31
  6. data/UPDATES.md +46 -9
  7. data/lib/simple2ch.rb +67 -83
  8. data/lib/simple2ch/bbs.rb +54 -0
  9. data/lib/simple2ch/board.rb +26 -50
  10. data/lib/simple2ch/dat.rb +22 -20
  11. data/lib/simple2ch/regex.rb +16 -0
  12. data/lib/simple2ch/{res.rb → response.rb} +58 -57
  13. data/lib/simple2ch/simple2ch_error.rb +9 -0
  14. data/lib/simple2ch/thread.rb +113 -0
  15. data/lib/simple2ch/version.rb +1 -1
  16. data/simple2ch.gemspec +8 -0
  17. data/spec/bbs_spec.rb +30 -0
  18. data/spec/board_spec.rb +89 -54
  19. data/spec/dat_spec.rb +20 -19
  20. data/spec/response_spec.rb +131 -0
  21. data/spec/simple2ch_spec.rb +19 -50
  22. data/spec/spec_helper.rb +65 -37
  23. data/spec/thread_spec.rb +76 -0
  24. data/spec/vcr/Simple2ch_BBS/_boards/use_cache/behaves_like_boards/from_2ch_sc/1_1_1_1_1_2.yml +1117 -0
  25. data/spec/vcr/Simple2ch_BBS/_boards/use_cache/behaves_like_boards/from_open2ch_net/1_1_1_1_2_2.yml +1136 -0
  26. data/spec/vcr/Simple2ch_BBS/_boards/use_force_reload/behaves_like_boards/from_2ch_sc/1_1_2_1_1_2.yml +1117 -0
  27. data/spec/vcr/Simple2ch_BBS/_boards/use_force_reload/behaves_like_boards/from_2ch_sc/1_1_2_1_1_3.yml +1117 -0
  28. data/spec/vcr/Simple2ch_BBS/_boards/use_force_reload/behaves_like_boards/from_open2ch_net/1_1_2_1_2_2.yml +1136 -0
  29. data/spec/vcr/Simple2ch_BBS/_boards/use_force_reload/behaves_like_boards/from_open2ch_net/1_1_2_1_2_3.yml +1136 -0
  30. data/spec/vcr/Simple2ch_Board/_threads/1_4_1.yml +1238 -0
  31. data/spec/vcr/Simple2ch_Board/_threads/1_4_2.yml +1238 -0
  32. data/spec/vcr/Simple2ch_Board/_threads/1_4_3.yml +1238 -0
  33. data/spec/vcr/Simple2ch_Board/_threads/1_4_7.yml +1238 -0
  34. data/spec/vcr/Simple2ch_Board/_threads/1_4_8.yml +1238 -0
  35. data/spec/vcr/Simple2ch_Board/_threads/1_4_9.yml +1238 -0
  36. data/spec/vcr/Simple2ch_Dat/should_have_responses/1_2_1.yml +953 -0
  37. data/spec/vcr/Simple2ch_Dat/should_have_responses/1_2_3.yml +953 -0
  38. data/spec/vcr/Simple2ch_Dat/should_have_responses/1_2_4.yml +953 -0
  39. data/spec/vcr/Simple2ch_Dat/should_have_responses/size/1_2_2_1.yml +953 -0
  40. data/spec/vcr/Simple2ch_Response/_anchors/when_a_thre_have_both_id_and_non-id_responses/1_2_7_1.yml +5321 -0
  41. data/spec/vcr/Simple2ch_Response/_parse/when_real_data/when_2ch_sc/1_1_2_1_1.yml +1599 -0
  42. data/spec/vcr/Simple2ch_Response/_parse/when_real_data/when_open2ch_net/1_1_2_2_1.yml +1465 -0
  43. data/spec/vcr/Simple2ch_Thread/_new/2ch_sc/1_1_1_1.yml +1410 -0
  44. data/spec/vcr/Simple2ch_Thread/_new/2ch_sc/1_1_1_2.yml +1692 -0
  45. data/spec/vcr/Simple2ch_Thread/_new/open2ch_net/1_1_2_1.yml +1410 -0
  46. data/spec/vcr/Simple2ch_Thread/_new/open2ch_net/1_1_2_2.yml +1999 -0
  47. data/spec/vcr/Simple2ch_Thread/_responses/1_2_1.yml +1599 -0
  48. data/spec/vcr/Simple2ch_Thread/_responses/first/1_2_2_1.yml +1599 -0
  49. data/spec/vcr/Simple2ch_Thread/_responses/first/1_2_3_1.yml +1599 -0
  50. data/spec/vcr/Simple2ch_Thread/_title/1_3_1.yml +1599 -0
  51. data/spec/vcr/Simple2ch_Thread/_title/size/1_3_2_1.yml +1599 -0
  52. metadata +185 -11
  53. data/lib/simple2ch/simple2ch_exception.rb +0 -7
  54. data/lib/simple2ch/thre.rb +0 -140
  55. data/spec/res_spec.rb +0 -123
  56. data/spec/thre_spec.rb +0 -122
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a828cfa87f21889ba2484cb3d9671f105ef269ae
4
- data.tar.gz: 2d966a2833cd5e664f0de975605f7f39c41c9d22
3
+ metadata.gz: 43d1380870c6d075419424891d4352ef6186d990
4
+ data.tar.gz: 4aee2a9072f121ffdb6cb8e2cbcf3fa4fb4abb37
5
5
  SHA512:
6
- metadata.gz: 2978f20a31058b412ea155168b9b5df645079f8938398a38f041ff17520e04958f13b7938cfb0e3d94bd4f90ad6b9416ceede5e58116222f81312b74775556a4
7
- data.tar.gz: e8b2bc6562634309cf9a87e5b2f487b82b5c8a4aefb3563588a01fca7fdd7d2dcc755e6e419106f13795a34987b56ba4c671fd23186ec6bacd927f9ff40650f9
6
+ metadata.gz: 90fe3acbd460eca6f3c405fffec2e4392a18c4adf65e8660289905c63cc61eebfc366cc8b9a18b2fd64e036b4628dbd5131b191893796dcb125b7638be01a018
7
+ data.tar.gz: 2f2dd214ed6f8579e257e07b98165ae4746e88c715a849c27d3c2712a8b19c375f959803cc92720b489483015ffea9241d80264f5238decd6f3b18581051ca75
data/.gitignore CHANGED
@@ -119,3 +119,4 @@ build/
119
119
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
120
120
  .rvmrc
121
121
 
122
+ .bin
data/.rubocop.yml ADDED
@@ -0,0 +1,25 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3
3
+ Includes:
4
+ - Gemfile
5
+ - Rakefile
6
+ Excludes:
7
+ - bin/**
8
+ - vendor/**
9
+ - .bundle/**
10
+
11
+ SymbolArray:
12
+ Enabled: true
13
+
14
+ CollectionMethods:
15
+ PreferredMethods:
16
+ collect: 'map'
17
+ inject: 'reduce'
18
+ detect: 'find'
19
+ find_all: 'select'
20
+
21
+ SpaceInsideHashLiteralBraces:
22
+ EnforcedStyleIsWithSpaces: false
23
+
24
+ Style/AsciiComments:
25
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.7
4
+ - 2.2.2
5
+ - 2.2.3
6
+ - 2.3.0
7
+ bundler_args: --jobs=2
8
+ script: bundle exec rspec
data/README.md CHANGED
@@ -4,18 +4,19 @@
4
4
  Ruby用の2chの簡易リーダーです。
5
5
 
6
6
  ![gem version](https://badge.fury.io/rb/simple2ch.svg)
7
- [リファレンス](http://dogwood008.github.io/simple2ch/)
7
+ [リファレンス](http://www.rubydoc.info/gems/simple2ch/)
8
8
 
9
9
  ## 更新内容
10
10
 
11
- * [v0.1.8]
12
- * 機能追加
13
- * URLからスレを取得した時に,subject.txtに当該スレが無い場合,タイトルをdatの解析結果から取得するよう変更
14
- * [v0.1.7]
15
- * 機能追加
16
- * Thre#url, Thre#dat_urlの追加
17
- * バグ修正
18
- * エンコーディング関連
11
+ ## [v1.1.0]
12
+
13
+ * 全面的にメソッド数を見直し、大幅なリファクタリング
14
+ * v0.X 系とは互換性一部なし
15
+ * クラス名変更: Res -> Response, Thre -> Thread
16
+
17
+ ## [v0.1.9]
18
+
19
+ * 著者をプレインテキストで返すメソッドを追加
19
20
 
20
21
  ## Installation
21
22
 
@@ -38,48 +39,41 @@ Or install it yourself as:
38
39
  require 'simple2ch'
39
40
  ```
40
41
 
41
- ### Simple2ch
42
+ ### Simple2ch:BBS
42
43
 
43
44
  ```ruby
44
- boards = Simple2ch.boards 'http://open2ch.net' #=> [#<Simple2ch::Board>, ..., #<Simple2ch::Board>]
45
+ bbs = Simple2ch::BBS(:sc)
46
+ bbs.boards #=> [#<Simple2ch::Board>, ...]
45
47
  ```
46
48
 
47
49
  ### Simple2ch::Board
50
+
48
51
  ```ruby
49
- board = boards.find{|b| b.title == 'プログラム'} #=> #<Simple2ch::Board>
50
- board.title #=> "プログラム"
51
- board.thres #=> [#<Simple2ch::Thre>, ..., #<Simple2ch::Thre>]
52
+ news_boards = bbs.boards.find_all { |b| b.title.include?('ニュース') } #=> [#<Simple2ch::Board>...]
53
+ news_board = news_boards.first
54
+ news_board.title #=> "ニュース速報α"
55
+ news_board.threads #=> [#<Simple2ch::Thread>, ...]
52
56
  ```
53
57
 
54
58
  ### Simple2ch::Thre
55
59
 
56
60
  ```ruby
57
- thre = board.thres.find{|t| t.title == 'さぁRubyはじめるよ'} #=> #<Simple2ch::Thre>
58
- reses = thre.reses #=> [#<Simple2ch::Res>, ..., #<Simple2ch::Res>]
61
+ thread = news_board.threads.first
62
+ thread.resonses #=> [#<Simple2ch::Response>, ...]
59
63
  ```
60
64
 
61
65
  #### URLを直接指定して取得
62
66
 
63
67
  ```ruby
64
- thre = Simple2ch::Thre.create_from_url('http://toro.open2ch.net/test/read.cgi/tech/1371956681/l50') #=> #<Simple2ch::Thre>
65
- thre.title #=> "さぁRubyはじめるよ"
66
- reses = thre.reses
67
- ```
68
-
69
- #### 板を指定して取得
70
-
71
- ```ruby
72
- board = Simple2ch::Board.new('ニュー速VIP', 'http://viper.open2ch.net/news4vip/')
73
- thres = board.thres #=>[#<Simple2ch::Thre>, ..., #<Simple2ch::Thre>]
74
- thre = thres.find{|t| t.title == 'プログラム'}
75
- reses = thre.reses
68
+ thread = Simple2ch::Thread.new('http://toro.open2ch.net/test/read.cgi/tech/1371956681/') #=> #<Simple2ch::Thre>
69
+ thread.title #=> "さぁRubyはじめるよ"
76
70
  ```
77
71
 
78
-
79
72
  ### Simple2ch::Res
80
73
 
81
74
  ```ruby
82
- res = reses[0] #=> #<Simple2ch::Res>
75
+ thread.responses #=> [#<Simple2ch::Response>, ...]
76
+ res = thread.responses[0] #=> #<Simple2ch::Response>
83
77
  res.res_num #=> 1
84
78
  res.contents #=> "Ruby覚えたいなぁ"
85
79
  res.author #=> "s"
@@ -88,7 +82,6 @@ res.date #=> 2013-06-23 12:04:41 +0900
88
82
  res.mail #=> ""
89
83
  ```
90
84
 
91
-
92
85
  ## Contributing
93
86
 
94
87
  1. Fork it ( https://github.com/dogwood008/simple2ch/fork )
data/UPDATES.md CHANGED
@@ -1,20 +1,53 @@
1
- [v0.1.5]
1
+ ## [v1.1.0]
2
+
3
+ * 全面的にメソッド数を見直し、大幅なリファクタリング
4
+ * v0.X 系とは互換性一部なし
5
+ * クラス名変更: Res -> Response, Thre -> Thread
6
+
7
+ ## [v0.1.9]
8
+
9
+ * 著者をプレインテキストで返すメソッドを追加
10
+
11
+ ## [v0.1.8]
12
+
13
+ * 機能追加
14
+ * URLからスレを取得した時に,subject.txtに当該スレが無い場合,タイトルをdatの解析結果から取得するよう変更
15
+
16
+ ## [v0.1.7]
17
+
18
+ * 機能追加
19
+ * Thre#url, Thre#dat_urlの追加
20
+ * バグ修正
21
+ * エンコーディング関連
22
+
23
+ ## [v0.1.6]
24
+
25
+ * 機能追加
26
+ * 板一覧の取得に対応
27
+ * URLからスレの取得に対応
28
+
29
+
30
+ ## [v0.1.5]
31
+
2
32
  * デバッグ
3
33
  * StandardErrorで例外を捕縛できない問題を修正
4
34
  * 機能追加
5
35
  * おーぷん2ちゃんねる対応
6
-
7
- [v0.1.4]
36
+
37
+ ## [v0.1.4]
38
+
8
39
  * デバッグ
9
40
  * Thre#resesを実行した際に、IDを持たないレスがあれば、DatParseExceptionが起きる問題を修正
10
41
  * エイリアス追加
11
42
  * Thre#resをThre#resesのエイリアスに設定
12
43
 
13
- [v0.1.3]
44
+ ## [v0.1.3]
45
+
14
46
  * デバッグ
15
47
  * Res#received_anchors呼び出し時にNoThreGivenExceptionが起きる場合がある問題を修正
16
48
 
17
- [v0.1.2]
49
+ ## [v0.1.2]
50
+
18
51
  * リファクタリングとデバッグ
19
52
  * メソッド修正
20
53
  * Thre#reses(Array<Fixnum>)で指定したレス番号のレスを取得
@@ -25,14 +58,16 @@
25
58
  * Res#received_anchors(Thre)
26
59
  * 自レスへの被レスを返す
27
60
 
28
- [v0.1.1]
61
+ ## [v0.1.1]
62
+
29
63
  * メソッド追加
30
64
  * Res#anchorsの追加
31
65
  * レス中のアンカーを抽出する
32
66
  * 必要gemの追加
33
67
  * Charwidthを追加
34
68
 
35
- [v0.1.0]
69
+ ## [v0.1.0]
70
+
36
71
  * メソッド名の変更
37
72
  * Thre.new から Thre.parse に変更
38
73
  * Thre.newは引数の数を変更
@@ -42,7 +77,8 @@
42
77
  * その他
43
78
  * その他微細な修正
44
79
 
45
- [v0.0.2]
80
+ ## [v0.0.2]
81
+
46
82
  * メソッド名の変更
47
83
  * Board#threads から Board#thres に変更
48
84
  * ドキュメントの再生成
@@ -51,5 +87,6 @@
51
87
  * 使用法などを追加
52
88
  * yardの結果を追加
53
89
 
54
- [v0.0.1]
90
+ ## [v0.0.1]
91
+
55
92
  * 初版
data/lib/simple2ch.rb CHANGED
@@ -1,108 +1,92 @@
1
- require "simple2ch/version"
1
+ require 'simple2ch/version'
2
+ require 'singleton'
2
3
 
3
4
  module Simple2ch
4
- DEBUG = false
5
-
6
- require 'simple2ch/simple2ch_exception'
7
- require 'simple2ch/board'
8
- require 'simple2ch/dat'
9
- require 'simple2ch/res'
10
- require 'simple2ch/thre'
5
+ require_relative './simple2ch/simple2ch_error'
6
+ require_relative './simple2ch/board'
7
+ require_relative './simple2ch/dat'
8
+ require_relative './simple2ch/response'
9
+ require_relative './simple2ch/thread'
10
+ require_relative './simple2ch/regex'
11
+ require_relative './simple2ch/bbs'
12
+ require 'socket'
11
13
  require 'open-uri'
12
14
  require 'time'
13
15
  require 'charwidth'
14
- require 'pp' if DEBUG
15
-
16
- def self.root
17
- File.dirname __dir__
18
- end
19
-
20
- # Module variables
21
- @@boards = {}
16
+ require 'retryable'
17
+ require 'bbs_2ch_url_validator'
18
+ require 'pry'
22
19
 
23
20
  # HTTPでGETする
24
- # @param [URI] url URL
21
+ # @param [URI or Bbs2chUrlValidator::UrlInfo or String] url URL
25
22
  # @return [String] 取得本文
26
- def self.fetch(url)
27
- encode = if url.to_s.index('subject.txt') || url.to_s.index('.dat') || url.to_s.index('bbsmenu')
28
- 'SHIFT_JIS'
29
- else
30
- 'UTF-8'
31
- end
32
- OpenURI.open_uri(url, 'r:binary').read.force_encoding(encode).encode('utf-8', undef: :replace, invalid: :replace, replace: '〓')
33
- end
34
-
35
- # bbsmenuのURLが渡されればセットして,板リストを返す
36
- # @param [String] bbsmenu_url bbs_menuのURL
37
- # @option [Boolean] force_refresh キャッシュを利用せず板リストを再取得する
38
- # @return [Array<Simple2ch::Board>] 板リスト
39
- def self.boards(bbsmenu_url=nil, force_refresh:nil)
40
- if bbsmenu_url
41
- bbsmenu_urls = {
42
- net: 'http://menu.2ch.net/bbsmenu.html', sc: 'http://2ch.sc/bbsmenu.html', open: 'http://open2ch.net/bbsmenu.html'
43
- }
44
- # http://www.rubular.com/r/u1TJbQAULD
45
- board_extract_regex = /<A HREF=http:\/\/(?<subdomain>\w+).(?<openflag>open|)2ch.(?<tld>sc|net)\/(?<board_name>\w+)\/>(?<board_name_ja>.+)<\/A>/
46
- type_of_2ch = self.type_of_2ch(bbsmenu_url)
47
-
48
- if force_refresh || (boards=@@boards.fetch(type_of_2ch, [])).size == 0
49
- prepared_bbsmenu_url = bbsmenu_urls[type_of_2ch]
50
-
51
- data = nil
52
- boards_array = []
53
-
54
- raise RuntimeError, "Failed to fetch #{url}" if (data = fetch(URI.parse(prepared_bbsmenu_url))).empty?
55
- raise RuntimeError, "Failed to parse #{url}" if (boards_array=data.scan(board_extract_regex).uniq).empty?
56
-
57
- boards_array.each do |b|
58
- boards << Simple2ch::Board.new(b[4],"http://#{b[0]}.#{b[1]}2ch.#{b[2]}/#{b[3]}/")
59
- end
60
- @@boards[type_of_2ch] = boards
61
- end
23
+ def self.fetch(url, encode = nil)
24
+ url_obj = URI.parse(url.to_s)
25
+ encode ||= encoded_in_sjis?(url) ? 'sjis' : 'utf-8'
26
+ errors_to_retry = [OpenURI::HTTPError, SocketError]
27
+ Retryable.retryable(tries: 5, on: errors_to_retry, sleep: 3) do
28
+ OpenURI.open_uri(url_obj, "r:#{encode}")
29
+ .read
30
+ .encode('utf-8', undef: :replace, invalid: :replace, replace: '〓')
62
31
  end
63
- @@boards[type_of_2ch]
64
32
  end
65
33
 
66
34
  # 2chのタイプを返す
67
35
  # @param [String] url URL
68
36
  # @return [Symbol] :open or :net or :sc
69
- # @raise [NotA2chUrlException] 2chのURLでないURLが与えられた際に発生
37
+ # @raise [NotA2chUrlError] 2chのURLでないURLが与えられた際に発生
70
38
  def self.type_of_2ch(url)
71
- parsed_url = self.parse_url(url)
72
- openflag = parsed_url[:openflag]
73
- tld = parsed_url[:tld]
74
- if openflag && tld=='net'
39
+ parsed_url = Bbs2chUrlValidator::URL.parse(url)
40
+ raise NotA2chUrlError, "Given URL: #{url}" unless parsed_url
41
+ case true
42
+ when parsed_url.is_open && parsed_url.tld == 'net'
75
43
  :open
76
- elsif !openflag && tld=='net'
44
+ when !parsed_url.is_open && parsed_url.tld == 'net'
77
45
  :net
78
- elsif !openflag && tld=='sc'
46
+ when !parsed_url.is_open && parsed_url.tld == 'sc'
79
47
  :sc
80
48
  else
81
- raise NotA2chUrlException, "Given URL: #{url}"
49
+ binding.pry
50
+ raise NotA2chUrlError, "Given URL: #{url}"
82
51
  end
83
52
  end
84
53
 
85
- # URLを分解する
86
- # @param [String] url URL
87
- # @return [Array<String>] 結果(thread_key等が該当無しの場合,nilを返す)
88
- # @raise [NotA2chUrlException] 2chのURLでないURLが与えられた際に発生
89
- def self.parse_url(url)
90
- # http://www.rubular.com/r/h63xdfmQIH
91
- case url.to_s
92
- when /http:\/\/(?<server_name>.+)\.(?<openflag>open)?2ch.(?<tld>net|sc)\/test\/read.cgi\/(?<board_name>.+)\/(?<thread_key>[0-9]+)/,
93
- /http:\/\/(?<server_name>.+)\.(?<openflag>open)?2ch.(?<tld>net|sc)\/(?<board_name>.+)\/subject\.txt/,
94
- /http:\/\/(?<server_name>.+)\.(?<openflag>open)?2ch\.(?<tld>net|sc)\/(?<board_name>.+)\//,
95
- /http:\/\/(?<server_name>.+)\.(?<openflag>open)?2ch\.(?<tld>net|sc)\/(?<board_name>\w+)/,
96
- /http:\/\/(?<server_name>.+)\.(?<openflag>open)?2ch.(?<tld>net|sc)\/(.+)\/dat\/(?<thread_key>[0-9]+)\.dat/,
97
- /http:\/\/(?:(?<server_name>.*)\.)?(?:(?<openflag>open)?)2ch\.(?<tld>sc|net)/
98
- {server_name: ($~[:server_name] rescue nil),
99
- board_name: ($~[:board_name] rescue nil),
100
- openflag: ($~[:openflag] rescue nil),
101
- tld: $~[:tld],
102
- thread_key: ($~[:thread_key] rescue nil) }
103
- else
104
- raise NotA2chUrlException, "Given URL: #{url}"
54
+ # @param [Object] url
55
+ # @param [Hash] type
56
+ def self.generate_url(type, url, params = {})
57
+ # bbs: http://www.2ch.sc/, http://open2ch.net/
58
+ # board: http://viper.2ch.sc/news4vip/, http://viper.open2ch.net/news4vip/
59
+ # dat: http://viper.2ch.sc/news4vip/dat/9990000001.dat, http://viper.open2ch.net/news4vip/dat/1439127670.dat
60
+ # subject: http://viper.2ch.sc/news4vip/subject.txt, http://viper.open2ch.net/news4vip/subject.txt
61
+ # setting: http://viper.2ch.sc/news4vip/SETTING.TXT, http://viper.open2ch.net/news4vip/SETTING.TXT
62
+ # thread: http://viper.2ch.sc/test/read.cgi/news4vip/9990000001/, http://viper.open2ch.net/test/read.cgi/news4vip/1439127670
63
+
64
+ url_obj = Bbs2chUrlValidator::URL.parse(url.to_s)
65
+ domain = "#{url_obj.open? ? 'open' : ''}2ch.#{url_obj.tld}"
66
+ board_name = params[:board_name] ? params[:board_name] : url_obj.board_name
67
+ case type
68
+ when :bbs
69
+ "http://www.#{domain}.#{url_obj.tld}/"
70
+ when :board
71
+ "http://#{url_obj.server_name}.#{domain}/#{board_name}/"
72
+ when :dat
73
+ url_obj.dat
74
+ when :subject
75
+ url_obj.subject
76
+ when :setting
77
+ url_obj.setting
78
+ when :thread
79
+ thread_key = params[:thread_key] ? params[:thread_key] : url_obj.thread_key
80
+ "http://#{url_obj.server_name}.#{domain}/test/read.cgi/#{board_name}/#{thread_key}/"
105
81
  end
106
82
  end
107
- end
108
83
 
84
+ private
85
+
86
+ def self.encoded_in_sjis?(url)
87
+ url.to_s.include?('subject.txt') ||
88
+ url.to_s.include?('SETTING.TXT') ||
89
+ url.to_s.include?('.dat') ||
90
+ url.to_s.include?('bbsmenu')
91
+ end
92
+ end
@@ -0,0 +1,54 @@
1
+ module Simple2ch
2
+ require 'socket'
3
+ require 'open-uri'
4
+ require 'time'
5
+ require 'charwidth'
6
+ require 'retryable'
7
+
8
+ class BBS
9
+ attr_reader :type_of_2ch, :boards, :updated_at
10
+
11
+ def initialize(type_of_2ch)
12
+ case type_of_2ch
13
+ when :sc, :open
14
+ @type_of_2ch = type_of_2ch
15
+ else
16
+ raise %{Invalid "type_of_2ch" given: #{type_of_2ch} (:sc or :open is correct.)}
17
+ end
18
+ @updated_at = Time.now
19
+ end
20
+
21
+ def root
22
+ File.dirname __dir__
23
+ end
24
+
25
+ # @option [Boolean] force_reload キャッシュを利用せず板リストを再取得する
26
+ # @return [Array<Simple2ch::Board>] 板リスト
27
+ def boards(force_reload: nil, bbsmenu_url: nil)
28
+ if force_reload
29
+ @boards = fetch_boards(bbsmenu_url)
30
+ else
31
+ @boards ||= fetch_boards(bbsmenu_url)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def fetch_boards(bbsmenu_url = nil)
38
+ bbsmenu_urls = {
39
+ sc: 'http://2ch.sc/bbsmenu.html', open: 'http://open2ch.net/bbsmenu.html'
40
+ }
41
+
42
+ bbsmenu_url = bbsmenu_urls[type_of_2ch] if bbsmenu_url.nil?
43
+ data = Simple2ch.fetch(URI.parse(bbsmenu_url))
44
+ raise "Failed to fetch #{bbsmenu_url}" if data.empty?
45
+ scaned_data = data.scan(Regex::BOARD_EXTRACT_REGEX).uniq
46
+ raise "Failed to parse #{bbsmenu_url}" if scaned_data.empty?
47
+
48
+ boards = scaned_data.map do |b|
49
+ Simple2ch::Board.new("http://#{b[0]}.#{b[1]}2ch.#{b[2]}/#{b[3]}/", title: b[4])
50
+ end
51
+ boards.compact
52
+ end
53
+ end
54
+ end