sleeproom 0.1.1 → 0.4.1

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: 0154be3d205feeac7e626a12dce7c76e54253c9731d926e35aab1478e046f5f5
4
- data.tar.gz: 93ed191055cbe4af6c73890bb50daadef4296857ba1f90f2b924547aefbfa92d
3
+ metadata.gz: 8e8ca3fc07a7a4dc3ed69aec76ad0d267bcaa60a9b4ef5c0adea7d068fe2c592
4
+ data.tar.gz: 78b13ce764ae80d0b48d9ca5fa59c8bfe929572b90f3baa248d8412068ff606d
5
5
  SHA512:
6
- metadata.gz: d9d8f2c0ddb0cad2c30c8bb9c3f9719eb9585c1895b0e114f97f11d534c52372925225a9b61dfbb89be05605e6e6637e801ba547417626dfde035b1b7ea94620
7
- data.tar.gz: 5d1b0e70df00ae7e069f9af9a41c751445d8a9ab24f0223f573ab7e8e61064eb2ab82a91193ebf65c0e94face9e906254928b85335bd72ca6b37621fd2281a76
6
+ metadata.gz: 69ebf1096e11fe91773de30d73b2c6801a851e85680bbcf5e94839a9e546f0268528bea9f7940862c882eda2da838c5485f957fbabe03fa57ca718b9e1c324b1
7
+ data.tar.gz: 076171c25ac3a74bcde2104f7db59e3cfbd549319a820a35e689eaee267f539fa6c17d104510b9a6c364c6d3dbca0bae83fff13bd5008a5a9f4915ab88cf05c5
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sleeproom (0.1.1)
5
- async
6
- async-http-faraday
7
- async-websocket
8
- colorize
9
- configatron
10
- terminal-table
4
+ sleeproom (0.4.1)
5
+ async (~> 1.26.0)
6
+ async-http-faraday (~> 0.9.0)
7
+ async-websocket (~> 0.15.0)
8
+ colorize (~> 0.8.0)
9
+ configatron (~> 4.5.0)
10
+ terminal-table (~> 1.8.0)
11
11
 
12
12
  GEM
13
13
  remote: https://rubygems.org/
@@ -1,6 +1,7 @@
1
+ #!/usr/bin/env ruby
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require "sleeproom/cli"
4
5
 
5
6
  cli = SleepRoom::CLI.new(ARGV)
6
- cli.run
7
+ cli.run
@@ -8,6 +8,7 @@ module SleepRoom
8
8
  class CLI
9
9
  # @param argv [Array]
10
10
  def initialize(argv)
11
+ SleepRoom.reload_config
11
12
  @options = {}
12
13
  build
13
14
  unless argv.empty?
@@ -17,8 +18,6 @@ module SleepRoom
17
18
  SleepRoom::Record::Tasks.status
18
19
  elsif action == "start"
19
20
  SleepRoom::Record::Tasks.start
20
- elsif action == "download"
21
- raise "未实现"
22
21
  elsif action == "exit"
23
22
  SleepRoom::Record::Tasks.stop
24
23
  end
@@ -53,18 +52,24 @@ module SleepRoom
53
52
  SleepRoom::Record::Tasks.add(room[0].to_s, room[1].to_s)
54
53
  end
55
54
 
56
- opt.on("-r", "--remove [URL]", "从监视列表移除") do |room|
55
+ opt.on("-r", "--remove [ROOM]", "从监视列表移除") do |room|
57
56
  SleepRoom::Record::Tasks.remove(room)
58
57
  end
59
58
 
60
- opt.on("-v", "--verbose", "Print log") do
61
- @options[:verbose] = true
59
+ opt.on("-d", "--download [ROOM]", "录制指定房间") do |room|
60
+ raise Error.new("房间名不能为空") if room.nil?
61
+ if room.match?("https://www.showroom-live.com/")
62
+ room = room.match(/https:\/\/www.showroom-live.com\/(.*)/)[1]
63
+ end
64
+ write_status = SleepRoom::Record::WriteStatus.new
65
+ record = SleepRoom::Record::Showroom.new(room: room, group: "download", queue: write_status)
66
+ record.record
62
67
  end
63
68
 
64
- opt.on("-d", "daemon", "Daemonize the script into the background") do
65
- @options[:daemon] = true
69
+ opt.on("-v", "--verbose", "Print log") do
70
+ @options[:verbose] = true
66
71
  end
67
-
72
+
68
73
  opt.on_tail("--version", "Print version") do
69
74
  STDOUT.puts(opt.version)
70
75
  end
@@ -10,6 +10,7 @@ module SleepRoom
10
10
  module Record
11
11
  module API
12
12
  class Error < StandardError; end
13
+ class NotFoundError < Error; end
13
14
  ROOM_URL = "https://www.showroom-live.com"
14
15
  ROOM_API = "https://www.showroom-live.com/api/room/status"
15
16
  STREAMING_API = "https://www.showroom-live.com/api/live/streaming_url"
@@ -21,6 +22,8 @@ module SleepRoom
21
22
  http = Faraday.get(url, nil, {"User-Agent": USER_AGENT})
22
23
  if http.status == 200
23
24
  @json = JSON.parse(http.body)
25
+ elsif http.status == 404
26
+ raise NotFoundError
24
27
  else
25
28
  raise Error, "HTTP Error: #{http.status}"
26
29
  end
@@ -15,7 +15,11 @@ module SleepRoom
15
15
  end
16
16
 
17
17
  def streaming_url
18
- @json["streaming_url_list"].sort_by{|hash| -hash["quality"]}.first["url"]
18
+ if @json["streaming_url_list"].nil?
19
+ raise Error.new("streaming url is null.")
20
+ else
21
+ @json["streaming_url_list"].sort_by{|hash| -hash["quality"]}.first["url"]
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -19,12 +19,12 @@ module SleepRoom
19
19
  def record(reconnection: false)
20
20
  room = @room
21
21
  Async do |task|
22
- api = API::RoomAPI.new(room)
22
+ set_room_info
23
23
  task.async do |t|
24
- while api.live?
24
+ while @is_live
25
25
  if status = SleepRoom.load_config(:status).find{|hash| hash[:room] == room}
26
26
  if !status[:pid].nil?
27
- break if SleepRoom.running?(pid) == false
27
+ break if SleepRoom.running?(status[:pid]) == false
28
28
  else
29
29
  break
30
30
  end
@@ -34,11 +34,6 @@ module SleepRoom
34
34
  t.sleep 60
35
35
  end
36
36
  end.wait
37
- @room_id = api.room_id
38
- @room_name = api.room_name
39
- @is_live = api.live?
40
- @broadcast_host = api.broadcast_host
41
- @broadcast_key = api.broadcast_key
42
37
  if @is_live
43
38
  start_time = Time.now
44
39
  log("Live broadcast.")
@@ -55,12 +50,7 @@ module SleepRoom
55
50
  if @running == false && @reconnection == false
56
51
  start_websocket
57
52
  elsif @reconnection == true
58
- api = API::RoomAPI.new(room)
59
- @room_id = api.room_id
60
- @room_name = api.room_name
61
- @is_live = api.live?
62
- @broadcast_host = api.broadcast_host
63
- @broadcast_key = api.broadcast_key
53
+ set_room_info
64
54
  start_websocket
65
55
  @reconnection = false
66
56
  end
@@ -122,15 +112,27 @@ module SleepRoom
122
112
  end
123
113
 
124
114
  Async do |task|
115
+ last_ack = nil
116
+ last_ping = nil
125
117
  while @running && @downlaoding == false
126
- status = ws.status
127
- if !status[:last_ack].nil? && Time.now.to_i - status[:last_ack].to_i > 65
118
+ queue = ws.queue.items
119
+ if !queue.empty?
120
+ queue.each do |event|
121
+ case event[:event]
122
+ when :ack
123
+ last_ack = event[:time]
124
+ when :ping
125
+ last_ping = event[:ping]
126
+ end
127
+ end
128
+ end
129
+ if !last_ack.nil? && Time.now.to_i - last_ack.to_i > 65
128
130
  ws.running = false
129
131
  @running = false
130
132
  task.stop
131
133
  end
132
- waiting_live(status)
133
- task.sleep 30
134
+ waiting_live({last_ack: last_ack})
135
+ task.sleep 1
134
136
  end
135
137
  end
136
138
  task.children.each(&:wait)
@@ -139,10 +141,31 @@ module SleepRoom
139
141
  @running = false
140
142
  end
141
143
  end
144
+
145
+ def set_room_info
146
+ api = API::RoomAPI.new(@room)
147
+ @room_id = api.room_id
148
+ @room_name = api.room_name
149
+ @is_live = api.live?
150
+ @broadcast_host = api.broadcast_host
151
+ @broadcast_key = api.broadcast_key
152
+ rescue API::NotFoundError
153
+ SleepRoom.error("[#{@room}] The room does not exist.")
154
+ log("Task stopped.")
155
+ Async::Task.current.stop
156
+ rescue => e
157
+ SleepRoom.error(e.message)
158
+ log("[setRoomInfo] Retry...")
159
+ retry
160
+ end
142
161
 
143
162
  def parse_streaming_url(task: Async::Task.current)
144
163
  api = API::StreamingAPI.new(@room_id)
145
164
  streaming_url_list = api.streaming_url
165
+ rescue => e
166
+ SleepRoom.error(e.full_message)
167
+ log("[parseStreamingUrl] Retry...")
168
+ retry
146
169
  end
147
170
 
148
171
  def build_output(task: Async::Task.current)
@@ -167,8 +190,9 @@ module SleepRoom
167
190
  download_pid: pid
168
191
  })
169
192
  task.async do |t|
170
- while true
171
- if !SleepRoom.running?(pid) && !API::RoomAPI.new(@room).live?
193
+ loop do
194
+ live = API::RoomAPI.new(@room).live?
195
+ if !SleepRoom.running?(pid) && !live
172
196
  log("Download complete.")
173
197
  @downlaoding = false
174
198
  @queue.add({
@@ -179,8 +203,18 @@ module SleepRoom
179
203
  status: :complete,
180
204
  })
181
205
  break
206
+ elsif live && !SleepRoom.running?(pid)
207
+ log("Minyami crash.")
208
+ streaming_url = parse_streaming_url
209
+ output = build_output
210
+ pid = SleepRoom::Record.call_minyami(url: streaming_url, output: output)
211
+ elsif !live && SleepRoom.running?(pid)
212
+ log("Live stop.")
182
213
  end
183
- t.sleep 60
214
+ t.sleep 120
215
+ rescue Faraday::ConnectionFailed
216
+ log("Network error.")
217
+ retry
184
218
  end
185
219
  end.wait
186
220
  end
@@ -6,12 +6,13 @@ require "json"
6
6
  module SleepRoom
7
7
  module Record
8
8
  class WebSocket
9
+ attr_accessor :queue
9
10
  def initialize(room:, broadcast_key:, url:)
10
11
  @room = room
11
12
  @url = "wss://" + url
12
13
  @broadcast_key = broadcast_key
13
14
  @running = false
14
- @status = {}
15
+ @queue = Async::Queue.new
15
16
  end
16
17
 
17
18
  def connect(task: Async::Task.current)
@@ -23,12 +24,12 @@ module SleepRoom
23
24
  connection.write("SUB\t#{@broadcast_key}")
24
25
  connection.flush
25
26
  log("Connect to websocket server.")
26
- @status[:last_update] = Time.now
27
+ @queue.enqueue({event: :connect, time: Time.now})
27
28
 
28
29
  ping_task = task.async do |sub|
29
30
  while @running
30
31
  sub.sleep 60
31
- @status[:last_ping] = Time.now
32
+ @queue.enqueue({event: :ping, time: Time.now})
32
33
  connection.write("PING\tshowroom")
33
34
  connection.flush
34
35
  end
@@ -44,12 +45,10 @@ module SleepRoom
44
45
  end
45
46
 
46
47
  while message = connection.read
47
- @status[:last_update]
48
48
  if message == "ACK\tshowroom"
49
- @status[:last_ack] = Time.now if message == "ACK\tshowroom"
49
+ @queue.enqueue({event: :ack, time: Time.now}) if message == "ACK\tshowroom"
50
50
  end
51
51
  if message.start_with?("MSG")
52
- @status[:last_msg] = Time.now
53
52
  begin
54
53
  yield JSON.parse(message.split("\t")[2])
55
54
  rescue => e
@@ -79,10 +78,6 @@ module SleepRoom
79
78
  @connection.close
80
79
  end
81
80
 
82
- def status
83
- @status
84
- end
85
-
86
81
  def log(str)
87
82
  SleepRoom.info("[#{@room}] #{str}")
88
83
  end
@@ -4,6 +4,7 @@ require "configatron"
4
4
  require "colorize"
5
5
  require "fileutils"
6
6
  require "yaml"
7
+ require "logger"
7
8
 
8
9
  module SleepRoom
9
10
  class Error < StandardError; end
@@ -111,10 +112,6 @@ module SleepRoom
111
112
  file: {
112
113
  use: true,
113
114
  path: "#{sleeproom_dir}/log"
114
- },
115
- websocket: {
116
- log: true,
117
- ping_log: false
118
115
  }
119
116
  }
120
117
  }
@@ -197,18 +194,43 @@ module SleepRoom
197
194
  # @param string [String]
198
195
  # @return [nil]
199
196
  def self.info(string)
200
- STDOUT.puts("[INFO] #{string}".colorize(:white))
197
+ log(:info, "[INFO] #{string}".colorize(:white))
201
198
  end
202
199
 
203
200
  # @param string [String]
204
201
  # @return [nil]
205
202
  def self.warning(string)
206
- warn("[WARN] #{string}".colorize(:yellow))
203
+ log(:warning, "[WARN] #{string}".colorize(:yellow))
207
204
  end
208
205
 
209
206
  # @param string [String]
210
207
  # @return [nil]
211
208
  def self.error(string)
212
- STDOUT.puts("[ERROR] #{string}".colorize(:red))
209
+ log(:error, "[ERROR] #{string}".colorize(:red))
210
+ end
211
+
212
+ def self.log(type, log)
213
+ case type
214
+ when :info
215
+ puts(log)
216
+ when :warning
217
+ warn(log)
218
+ when :error
219
+ puts(log)
220
+ end
221
+ file_logger(type, log) if configatron.logger.file.use == true
222
+ end
223
+
224
+ def self.file_logger(type, log)
225
+ path = configatron.logger.file.path
226
+ logger = Logger.new(path)
227
+ case type
228
+ when :info
229
+ logger.info(log)
230
+ when :warning
231
+ logger.warning(log)
232
+ when :error
233
+ logger.error(log)
234
+ end
213
235
  end
214
236
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SleepRoom
4
- VERSION = "0.1.1"
4
+ VERSION = "0.4.1"
5
5
  end
@@ -25,12 +25,12 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = ["sleeproom"]
26
26
  spec.require_paths = ["lib"]
27
27
 
28
- spec.add_runtime_dependency("colorize")
29
- spec.add_runtime_dependency("async")
30
- spec.add_runtime_dependency("async-websocket")
31
- spec.add_runtime_dependency("configatron")
32
- spec.add_runtime_dependency("async-http-faraday")
33
- spec.add_runtime_dependency("terminal-table")
28
+ spec.add_runtime_dependency("colorize", "~> 0.8.0")
29
+ spec.add_runtime_dependency("async", "~> 1.26.0")
30
+ spec.add_runtime_dependency("async-websocket", "~> 0.15.0")
31
+ spec.add_runtime_dependency("configatron", "~> 4.5.0")
32
+ spec.add_runtime_dependency("async-http-faraday", "~> 0.9.0")
33
+ spec.add_runtime_dependency("terminal-table", "~> 1.8.0")
34
34
 
35
35
  spec.post_install_message = <<~STR
36
36
  SleepRoom 需要:
metadata CHANGED
@@ -1,99 +1,99 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sleeproom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-10 00:00:00.000000000 Z
11
+ date: 2020-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.8.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 0.8.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: async
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 1.26.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 1.26.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: async-websocket
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 0.15.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 0.15.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: configatron
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 4.5.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 4.5.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: async-http-faraday
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: 0.9.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: 0.9.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: terminal-table
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: 1.8.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: 1.8.0
97
97
  description:
98
98
  email:
99
99
  - i@wug.moe