sleeproom 0.4.3 → 0.9.0.pre1
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/Gemfile +3 -2
- data/Gemfile.lock +51 -17
- data/Rakefile +3 -1
- data/bin/sleeproom +1 -2
- data/lib/sleeproom/async/websocket.rb +8 -6
- data/lib/sleeproom/cli.rb +21 -19
- data/lib/sleeproom/record.rb +8 -5
- data/lib/sleeproom/record/api/api.rb +3 -7
- data/lib/sleeproom/record/api/room.rb +2 -1
- data/lib/sleeproom/record/api/room_api.rb +2 -1
- data/lib/sleeproom/record/api/streaming_api.rb +4 -3
- data/lib/sleeproom/record/record.rb +134 -182
- data/lib/sleeproom/record/tasks.rb +64 -55
- data/lib/sleeproom/record/web/app.rb +53 -0
- data/lib/sleeproom/record/websocket.rb +81 -66
- data/lib/sleeproom/record/write_status.rb +29 -2
- data/lib/sleeproom/utils.rb +37 -6
- data/lib/sleeproom/version.rb +1 -1
- data/sleeproom.gemspec +7 -3
- metadata +68 -11
|
@@ -1,69 +1,71 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require "terminal-table"
|
|
3
4
|
|
|
4
5
|
module SleepRoom
|
|
5
6
|
module Record
|
|
6
7
|
class Tasks
|
|
7
8
|
# @return [void]
|
|
8
|
-
def self.start
|
|
9
|
-
Async do |
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
SleepRoom.create_pid(Process.pid)
|
|
20
|
-
lists = SleepRoom.load_config(:record)
|
|
21
|
-
lists.each do |group, list|
|
|
22
|
-
SleepRoom.info("Empty list.") if list.empty?
|
|
23
|
-
list.each do |room|
|
|
24
|
-
record = SleepRoom::Record::Showroom.new(room: room["room"], group: group, queue: write_status)
|
|
25
|
-
record.record
|
|
26
|
-
count += 1
|
|
9
|
+
def self.start(verbose: false)
|
|
10
|
+
Async do |task|
|
|
11
|
+
begin
|
|
12
|
+
running_task_count = 0
|
|
13
|
+
write_status = WriteStatus.new
|
|
14
|
+
write_status.run
|
|
15
|
+
if SleepRoom.running?
|
|
16
|
+
SleepRoom.error("PID #{SleepRoom.load_pid} Process is already running.")
|
|
17
|
+
exit
|
|
18
|
+
else
|
|
19
|
+
SleepRoom.write_config_file(:status, [])
|
|
27
20
|
end
|
|
28
|
-
|
|
29
|
-
SleepRoom.
|
|
21
|
+
SleepRoom.create_pid(Process.pid)
|
|
22
|
+
lists = SleepRoom.load_config(:record)
|
|
23
|
+
lists.each do |group, list|
|
|
24
|
+
begin
|
|
25
|
+
SleepRoom.info("Empty list.") if list.empty?
|
|
26
|
+
list.each do |room|
|
|
27
|
+
Async do
|
|
28
|
+
running_task_count += 1
|
|
29
|
+
record = SleepRoom::Record::Showroom.new(room: room["room"], group: group, queue: write_status)
|
|
30
|
+
record.record
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
rescue StandardError
|
|
34
|
+
SleepRoom.error("Cannot parse Recording list.")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
SleepRoom.info("共启动 #{running_task_count} 个任务.")
|
|
38
|
+
if configatron.web.use
|
|
39
|
+
Async do
|
|
40
|
+
host = configatron.web.server.to_s
|
|
41
|
+
port = configatron.web.port.to_i
|
|
42
|
+
Rack::Handler.get(:falcon).run(Web::App, Host: host, Port: port)
|
|
43
|
+
SleepRoom.info("Web server running. http://#{host}:#{port}/")
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
task.children.each(&:wait)
|
|
47
|
+
rescue StandardError => e
|
|
48
|
+
puts e.full_message
|
|
30
49
|
end
|
|
31
|
-
write_status.run
|
|
32
|
-
SleepRoom.info("共启动 #{count} 个任务.")
|
|
33
|
-
wait
|
|
34
|
-
rescue => e
|
|
35
|
-
puts e.full_message
|
|
36
50
|
end
|
|
37
|
-
rescue Exception
|
|
51
|
+
rescue Exception => e
|
|
52
|
+
puts e.full_message if verbose
|
|
38
53
|
SleepRoom.create_pid(nil) unless SleepRoom.running?
|
|
39
54
|
puts "Exit..."
|
|
40
55
|
end
|
|
41
56
|
|
|
42
57
|
# @return [void]
|
|
43
58
|
def self.stop
|
|
44
|
-
SleepRoom.reload_config
|
|
45
59
|
raise "未实现"
|
|
46
60
|
end
|
|
47
61
|
|
|
48
62
|
# @return [void]
|
|
49
63
|
def self.status
|
|
50
64
|
Async do
|
|
51
|
-
SleepRoom.
|
|
52
|
-
status = SleepRoom.load_status
|
|
65
|
+
status = SleepRoom.load_status.sort_by { |hash| hash[:group] }
|
|
53
66
|
pid = SleepRoom.load_config(:pid)
|
|
54
67
|
if !SleepRoom.running?(pid) || status.empty? || pid.nil?
|
|
55
|
-
lists = SleepRoom.load_config(:record)
|
|
56
68
|
SleepRoom.info("No tasks running.")
|
|
57
|
-
lists.each do |group, list|
|
|
58
|
-
next if list.empty?
|
|
59
|
-
rows = []
|
|
60
|
-
title = group
|
|
61
|
-
headings = list[0].keys
|
|
62
|
-
list.each do |hash|
|
|
63
|
-
rows.push(hash.values)
|
|
64
|
-
end
|
|
65
|
-
puts Terminal::Table.new(title: "[Recording list] Group: #{title}",:rows => rows, headings: headings)
|
|
66
|
-
end
|
|
67
69
|
else
|
|
68
70
|
rows = []
|
|
69
71
|
headings = status[0].keys
|
|
@@ -71,7 +73,7 @@ module SleepRoom
|
|
|
71
73
|
rows.push(
|
|
72
74
|
hash.values.map do |s|
|
|
73
75
|
if s.is_a?(Hash)
|
|
74
|
-
|
|
76
|
+
((s[:last_ack].is_a?(Time) ? "[ACK]" + s[:last_ack].strftime("%H:%M:%S").to_s : "nil")).to_s
|
|
75
77
|
elsif s.is_a?(Time)
|
|
76
78
|
s.strftime("%H:%M:%S")
|
|
77
79
|
else
|
|
@@ -80,18 +82,34 @@ module SleepRoom
|
|
|
80
82
|
end
|
|
81
83
|
)
|
|
82
84
|
end
|
|
83
|
-
puts Terminal::Table.new(title: "Status [PID #{pid}] (#{status.count})"
|
|
85
|
+
puts Terminal::Table.new(title: "Status [PID #{pid}] (#{status.count})", rows: rows, headings: headings)
|
|
84
86
|
end
|
|
85
87
|
end
|
|
86
88
|
end
|
|
87
89
|
|
|
90
|
+
def self.lists
|
|
91
|
+
lists = SleepRoom.load_config(:record)
|
|
92
|
+
puts "[Record list]"
|
|
93
|
+
lists.each do |group, list|
|
|
94
|
+
next if list.empty?
|
|
95
|
+
|
|
96
|
+
rows = []
|
|
97
|
+
title = group
|
|
98
|
+
headings = list[0].keys
|
|
99
|
+
list.each do |hash|
|
|
100
|
+
rows.push(hash.values)
|
|
101
|
+
end
|
|
102
|
+
puts Terminal::Table.new(title: title, rows: rows, headings: headings)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
88
106
|
def self.add(room, group)
|
|
89
107
|
Async do
|
|
90
108
|
group = "default" if group.empty?
|
|
91
109
|
old_record = SleepRoom.load_config(:record)
|
|
92
110
|
name = API::RoomAPI.new(room).room_name
|
|
93
|
-
input_record = {"room" => room, "name" => name}
|
|
94
|
-
if !old_record[group].nil? &&
|
|
111
|
+
input_record = { "room" => room, "name" => name }
|
|
112
|
+
if !old_record[group].nil? && old_record[group].find { |h| h = input_record if h["room"] == room }
|
|
95
113
|
SleepRoom.error("Room #{room} already exists.")
|
|
96
114
|
else
|
|
97
115
|
old_record[group] = [] if old_record[group].nil?
|
|
@@ -105,19 +123,10 @@ module SleepRoom
|
|
|
105
123
|
|
|
106
124
|
def self.remove(room)
|
|
107
125
|
old_record = SleepRoom.load_config(:record)
|
|
108
|
-
new_record = old_record.each {|
|
|
126
|
+
new_record = old_record.each { |_k, v| v.delete_if { |h| h["room"] == room } }
|
|
109
127
|
SleepRoom.write_config_file(:record, new_record)
|
|
110
128
|
SleepRoom.info("Remove success.")
|
|
111
129
|
end
|
|
112
|
-
|
|
113
|
-
private
|
|
114
|
-
def self.wait
|
|
115
|
-
Async do |task|
|
|
116
|
-
while true
|
|
117
|
-
task.sleep 1
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
130
|
end
|
|
122
131
|
end
|
|
123
132
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "roda"
|
|
4
|
+
module SleepRoom
|
|
5
|
+
module Web
|
|
6
|
+
class App < Roda
|
|
7
|
+
plugin :default_headers,
|
|
8
|
+
"Content-Type" => "application/json",
|
|
9
|
+
"X-Frame-Options" => "deny",
|
|
10
|
+
"X-Content-Type-Options" => "nosniff",
|
|
11
|
+
"X-XSS-Protection" => "1; mode=block"
|
|
12
|
+
plugin :content_security_policy do |csp|
|
|
13
|
+
csp.default_src :none
|
|
14
|
+
csp.style_src :self
|
|
15
|
+
csp.form_action :self
|
|
16
|
+
csp.script_src :self
|
|
17
|
+
csp.connect_src :self
|
|
18
|
+
csp.base_uri :none
|
|
19
|
+
csp.frame_ancestors :none
|
|
20
|
+
end
|
|
21
|
+
plugin :public
|
|
22
|
+
plugin :multi_route
|
|
23
|
+
plugin :not_found do
|
|
24
|
+
end
|
|
25
|
+
plugin :error_handler do |e|
|
|
26
|
+
$stderr.print "#{e.class}: #{e.message}\n"
|
|
27
|
+
warn e.backtrace
|
|
28
|
+
next exception_page(e, assets: true) if ENV["RACK_ENV"] == "development"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
route "status" do |r|
|
|
32
|
+
SleepRoom.load_status.sort_by { |hash| hash[:group] }.to_json
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
route "lists" do |r|
|
|
36
|
+
r.get do
|
|
37
|
+
SleepRoom.load_config(:record).to_json
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
r.post do
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
route do |r|
|
|
44
|
+
r.public
|
|
45
|
+
r.multi_route
|
|
46
|
+
|
|
47
|
+
r.root do
|
|
48
|
+
"SleepRoom Web API"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -1,86 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "sleeproom/async/websocket"
|
|
2
4
|
require "async/http/endpoint"
|
|
3
5
|
require "async/websocket/client"
|
|
4
6
|
require "json"
|
|
5
7
|
|
|
6
8
|
module SleepRoom
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
module Record
|
|
10
|
+
class WebSocket
|
|
11
|
+
attr_accessor :last_ack
|
|
12
|
+
def initialize(room:, broadcast_key:, url:)
|
|
13
|
+
@room = room
|
|
14
|
+
@url = "wss://" + url
|
|
15
|
+
@broadcast_key = broadcast_key
|
|
16
|
+
@running = false
|
|
17
|
+
@last_ack = nil
|
|
18
|
+
end
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
def connect(task: Async::Task.current)
|
|
21
|
+
url = @url
|
|
22
|
+
endpoint = Async::HTTP::Endpoint.parse(url)
|
|
23
|
+
Async::WebSocket::Client.connect(endpoint, handler: WebSocketConnection) do |connection|
|
|
24
|
+
begin
|
|
25
|
+
@connection = connection
|
|
26
|
+
@running = true
|
|
27
|
+
connection.write("SUB\t#{@broadcast_key}")
|
|
28
|
+
connection.flush
|
|
29
|
+
log("Connect to websocket server.")
|
|
30
|
+
yield :status, { event: :connect, time: Time.now }
|
|
31
|
+
|
|
32
|
+
ping_task = task.async do |sub|
|
|
33
|
+
while @running
|
|
34
|
+
sub.sleep 60
|
|
35
|
+
connection.write("PING\tshowroom")
|
|
25
36
|
connection.flush
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
ping_task = task.async do |sub|
|
|
30
|
-
while @running
|
|
31
|
-
sub.sleep 60
|
|
32
|
-
@queue.enqueue({event: :ping, time: Time.now})
|
|
33
|
-
connection.write("PING\tshowroom")
|
|
34
|
-
connection.flush
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
end
|
|
45
|
-
end
|
|
40
|
+
status_task = task.async do |sub|
|
|
41
|
+
loop do
|
|
42
|
+
sub.sleep 1
|
|
43
|
+
connection.close if @running == false
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
SleepRoom.error(e.message)
|
|
56
|
-
end
|
|
47
|
+
reconnect_task = task.async do |t|
|
|
48
|
+
loop do
|
|
49
|
+
t.sleep 10
|
|
50
|
+
if !@last_ack.nil? && Time.now.to_i - @last_ack.to_i > 65
|
|
51
|
+
begin
|
|
52
|
+
yield :status, { event: :close, time: Time.now }
|
|
53
|
+
connection.close
|
|
54
|
+
rescue
|
|
57
55
|
end
|
|
58
56
|
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
while message = connection.read
|
|
60
|
+
if message == "ACK\tshowroom"
|
|
61
|
+
@last_ack = Time.now
|
|
62
|
+
yield :status, { event: :ack, time: Time.now } if message == "ACK\tshowroom"
|
|
63
|
+
end
|
|
64
|
+
next unless message.start_with?("MSG")
|
|
65
|
+
|
|
66
|
+
begin
|
|
67
|
+
yield :websocket, JSON.parse(message.split("\t")[2])
|
|
59
68
|
rescue => e
|
|
60
69
|
SleepRoom.error(e.message)
|
|
61
|
-
ensure
|
|
62
|
-
ping_task&.stop
|
|
63
|
-
connection.close
|
|
64
|
-
log("WebSocket closed.")
|
|
65
70
|
end
|
|
71
|
+
end
|
|
72
|
+
rescue => e
|
|
73
|
+
yield :status, { event: :error, error: e }
|
|
74
|
+
SleepRoom.error(e.message)
|
|
75
|
+
ensure
|
|
76
|
+
ping_task&.stop
|
|
77
|
+
status_task&.stop
|
|
78
|
+
connection.close
|
|
79
|
+
reconnect_task&.stop
|
|
80
|
+
log("WebSocket closed.")
|
|
66
81
|
end
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
@running
|
|
70
|
-
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
71
84
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
85
|
+
def running?
|
|
86
|
+
@running
|
|
87
|
+
end
|
|
75
88
|
|
|
76
|
-
|
|
77
|
-
@running = false
|
|
78
|
-
@connection.close
|
|
79
|
-
end
|
|
89
|
+
attr_writer :running
|
|
80
90
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
def stop
|
|
92
|
+
@running = false
|
|
93
|
+
@connection.close
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def log(str)
|
|
97
|
+
SleepRoom.info("[#{@room}] #{str}")
|
|
84
98
|
end
|
|
85
|
-
|
|
86
|
-
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -15,9 +15,11 @@ module SleepRoom
|
|
|
15
15
|
status[:update] = Time.now
|
|
16
16
|
old_status = SleepRoom.load_config(:status)
|
|
17
17
|
room = status[:room]
|
|
18
|
-
if old_status.find { |h| h[:room] == room }
|
|
18
|
+
if tmp_status = old_status.find { |h| h[:room] == room }
|
|
19
19
|
new_status = old_status.delete_if { |h| h[:room] == room }
|
|
20
|
-
|
|
20
|
+
unless tmp_status[:status] == :downloading && status[:status] == :waiting
|
|
21
|
+
new_status.push(tmp_status.merge!(status))
|
|
22
|
+
end
|
|
21
23
|
else
|
|
22
24
|
new_status = old_status.push(status)
|
|
23
25
|
end
|
|
@@ -31,6 +33,31 @@ module SleepRoom
|
|
|
31
33
|
@queue.enqueue(status)
|
|
32
34
|
end
|
|
33
35
|
end
|
|
36
|
+
|
|
37
|
+
def downloading(room:, url:, pid:, start_time:)
|
|
38
|
+
add(
|
|
39
|
+
{
|
|
40
|
+
room: room,
|
|
41
|
+
live: true,
|
|
42
|
+
status: :downloading,
|
|
43
|
+
streaming_url: url,
|
|
44
|
+
pid: pid,
|
|
45
|
+
start_time: start_time
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def waiting(room:, group:, room_name:)
|
|
51
|
+
add(
|
|
52
|
+
{
|
|
53
|
+
room: room,
|
|
54
|
+
live: false,
|
|
55
|
+
group: group,
|
|
56
|
+
name: room_name,
|
|
57
|
+
status: :waiting,
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
end
|
|
34
61
|
end
|
|
35
62
|
end
|
|
36
63
|
end
|
data/lib/sleeproom/utils.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "configatron"
|
|
4
4
|
require "colorize"
|
|
5
5
|
require "fileutils"
|
|
6
|
+
require "tmpdir"
|
|
6
7
|
require "yaml"
|
|
7
8
|
require "logger"
|
|
8
9
|
|
|
@@ -64,6 +65,7 @@ module SleepRoom
|
|
|
64
65
|
def self.create_config_file(config, settings)
|
|
65
66
|
path = config_path(config)
|
|
66
67
|
return false if File.exist?(path)
|
|
68
|
+
|
|
67
69
|
mkdir(File.dirname(path)) unless Dir.exist?(File.dirname(path))
|
|
68
70
|
write_config_file(config, settings)
|
|
69
71
|
end
|
|
@@ -105,7 +107,7 @@ module SleepRoom
|
|
|
105
107
|
default_save_name: "%ROOMNAME%-%TIME%.ts",
|
|
106
108
|
minyami: {
|
|
107
109
|
threads: 8,
|
|
108
|
-
retries: 999
|
|
110
|
+
retries: 999
|
|
109
111
|
},
|
|
110
112
|
logger: {
|
|
111
113
|
console: true,
|
|
@@ -122,9 +124,9 @@ module SleepRoom
|
|
|
122
124
|
mkdir(config_dir) unless Dir.exist?(config_dir)
|
|
123
125
|
|
|
124
126
|
mkdir("#{config_dir}/tmp") unless Dir.exist?("#{config_dir}/tmp")
|
|
125
|
-
|
|
127
|
+
|
|
126
128
|
init_base
|
|
127
|
-
|
|
129
|
+
|
|
128
130
|
record = {
|
|
129
131
|
"default" => []
|
|
130
132
|
}
|
|
@@ -150,6 +152,7 @@ module SleepRoom
|
|
|
150
152
|
def self.settings
|
|
151
153
|
configatron
|
|
152
154
|
end
|
|
155
|
+
|
|
153
156
|
def self.load_status
|
|
154
157
|
SleepRoom.load_config(:status)
|
|
155
158
|
rescue Error
|
|
@@ -164,11 +167,11 @@ module SleepRoom
|
|
|
164
167
|
retry
|
|
165
168
|
end
|
|
166
169
|
|
|
167
|
-
def self.running?(pid=nil)
|
|
170
|
+
def self.running?(pid = nil)
|
|
168
171
|
pid = SleepRoom.load_config(:pid) if pid.nil?
|
|
169
172
|
Process.kill(0, pid)
|
|
170
173
|
true
|
|
171
|
-
rescue
|
|
174
|
+
rescue StandardError
|
|
172
175
|
false
|
|
173
176
|
end
|
|
174
177
|
|
|
@@ -183,7 +186,7 @@ module SleepRoom
|
|
|
183
186
|
SleepRoom.create_config_file(:status, status)
|
|
184
187
|
end
|
|
185
188
|
|
|
186
|
-
def self.create_record(record = {default: []})
|
|
189
|
+
def self.create_record(record = { default: [] })
|
|
187
190
|
SleepRoom.create_config_file(:record, record)
|
|
188
191
|
end
|
|
189
192
|
|
|
@@ -192,6 +195,34 @@ module SleepRoom
|
|
|
192
195
|
SleepRoom.write_config_file(:pid, pid)
|
|
193
196
|
end
|
|
194
197
|
|
|
198
|
+
def self.find_tmp_directory(output, call_time)
|
|
199
|
+
regex = /Proccessing (.*) finished./
|
|
200
|
+
output = "#{configatron.save_path}/#{output}"
|
|
201
|
+
log = "#{output}.out"
|
|
202
|
+
if media_name = File.readlines(log).select { |line| line =~ regex }.last.match(regex)[1]
|
|
203
|
+
directories = Dir["#{Dir.tmpdir}/minyami_#{call_time.to_i / 10}*"]
|
|
204
|
+
directories.each do |path|
|
|
205
|
+
if Dir.glob("#{path}/*.ts").select{ |e| e.include?(media_name)}
|
|
206
|
+
next unless Dir.glob("#{path}/*.ts").last.include?(media_name)
|
|
207
|
+
|
|
208
|
+
return path
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
return false
|
|
213
|
+
rescue => e
|
|
214
|
+
puts e.full_message
|
|
215
|
+
SleepRoom.error("寻找失败.")
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def self.move_ts_to_archive(tmp, path, name)
|
|
219
|
+
FileUtils.cp_r(tmp, path)
|
|
220
|
+
FileUtils.mv(File.join(path, File.basename(tmp)), File.join(path, name))
|
|
221
|
+
rescue => e
|
|
222
|
+
puts e.full_message
|
|
223
|
+
SleepRoom.error("复制失败.")
|
|
224
|
+
end
|
|
225
|
+
|
|
195
226
|
# @param string [String]
|
|
196
227
|
# @return [nil]
|
|
197
228
|
def self.info(string)
|