scene-toolkit 0.1.5 → 0.1.6
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.
- data/VERSION +1 -1
- data/bin/scene-toolkit +7 -0
- data/lib/scene_toolkit/cli.rb +69 -26
- data/lib/scene_toolkit/release.rb +42 -33
- metadata +4 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.6
|
data/bin/scene-toolkit
CHANGED
@@ -5,6 +5,7 @@ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
|
5
5
|
require 'scene_toolkit'
|
6
6
|
|
7
7
|
Optitron.dispatch(SceneToolkit::CLI.new) do
|
8
|
+
help
|
8
9
|
cmd "verify", "Verify library or release. Executes all validations if none specified" do
|
9
10
|
arg "directory", "The root directory to verify"
|
10
11
|
opt "name", "Validate release name"
|
@@ -15,4 +16,10 @@ Optitron.dispatch(SceneToolkit::CLI.new) do
|
|
15
16
|
opt "move-invalid-to", "Move INVALID releases to specified folder", :type => :string
|
16
17
|
opt "move-valid-to", "Move VALID releases to specified folder", :type => :string
|
17
18
|
end
|
19
|
+
|
20
|
+
cmd "repair", "Repair releases" do
|
21
|
+
arg "directory", "The root directory to repair"
|
22
|
+
opt "playlist", "Repair wrong playlist or generate missing ones"
|
23
|
+
opt "force", "Force the modification of existing files"
|
24
|
+
end
|
18
25
|
end
|
data/lib/scene_toolkit/cli.rb
CHANGED
@@ -7,6 +7,41 @@ require 'optitron'
|
|
7
7
|
require 'rainbow'
|
8
8
|
|
9
9
|
class SceneToolkit::CLI
|
10
|
+
def repair(directory, opts)
|
11
|
+
opts.underscore_and_symbolize_keys!
|
12
|
+
|
13
|
+
each_release(directory) do |release|
|
14
|
+
if opts[:playlist]
|
15
|
+
unless release.valid_playlist?
|
16
|
+
puts release.name.foreground(:red)
|
17
|
+
puts release.path
|
18
|
+
print_errors(release)
|
19
|
+
|
20
|
+
candidates = release.files.select { |f| %w(.nfo .m3u .sfv).include?(File.extname(f).downcase) }.group_by { |f| File.basename(f, '.*') }
|
21
|
+
if candidates.none?
|
22
|
+
puts " ✕ Unable to guess playlist filename".foreground(:red)
|
23
|
+
next
|
24
|
+
end
|
25
|
+
|
26
|
+
playlist_filename = [candidates.max { |k, v| v.size }.first, ".m3u"].join
|
27
|
+
|
28
|
+
playlist_path = File.join(release.path, playlist_filename)
|
29
|
+
if File.exist?(playlist_path) and not opts[:force]
|
30
|
+
puts " ✕ Playlist #{playlist_filename} already exists. Use --force to replace it.".foreground(:red)
|
31
|
+
else
|
32
|
+
puts " ■ Generating new playlist: #{playlist_filename}".foreground(:yellow)
|
33
|
+
File.open(playlist_path, "w") do |playlist_file|
|
34
|
+
release.mp3_files.map { |f| File.basename(f) }.each do |mp3_file|
|
35
|
+
playlist_file.puts mp3_file
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
puts
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
10
45
|
def verify(directory, opts)
|
11
46
|
opts.underscore_and_symbolize_keys!
|
12
47
|
validations = []
|
@@ -34,46 +69,54 @@ class SceneToolkit::CLI
|
|
34
69
|
|
35
70
|
each_release(directory) do |release|
|
36
71
|
release_count += 1
|
37
|
-
|
38
|
-
if release_valid = release.valid?(validations)
|
72
|
+
if release.valid?(validations)
|
39
73
|
valid_releases += 1
|
40
|
-
|
74
|
+
if not opts[:hide_valid] or not valid_target_directory.nil?
|
75
|
+
puts release.name.foreground(:green)
|
76
|
+
puts release.path
|
77
|
+
print_errors(release)
|
78
|
+
print_warnings(release)
|
79
|
+
unless valid_target_directory.nil?
|
80
|
+
move_release(release, valid_target_directory)
|
81
|
+
end
|
82
|
+
puts
|
83
|
+
end
|
41
84
|
else
|
42
85
|
invalid_releases += 1
|
43
86
|
puts release.name.foreground(:red)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
errors.each do |error|
|
50
|
-
puts " ✕ #{error}".foreground(:red)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
release.warnings.each do |validation, warnings|
|
55
|
-
warnings.each do |warning|
|
56
|
-
puts " ✕ #{warning}".foreground(:yellow)
|
87
|
+
puts release.path
|
88
|
+
print_errors(release)
|
89
|
+
print_warnings(release)
|
90
|
+
unless invalid_target_directory.nil?
|
91
|
+
move_release(release, invalid_target_directory)
|
57
92
|
end
|
93
|
+
puts
|
58
94
|
end
|
59
|
-
|
60
|
-
unless valid_target_directory.nil?
|
61
|
-
move_release(release, valid_target_directory) if release_valid
|
62
|
-
end
|
63
|
-
|
64
|
-
unless invalid_target_directory.nil?
|
65
|
-
move_release(release, invalid_target_directory) unless release_valid
|
66
|
-
end
|
67
|
-
|
68
|
-
puts
|
69
95
|
end
|
70
96
|
|
97
|
+
puts
|
71
98
|
puts "#{valid_releases} of #{release_count} releases valid".foreground(:yellow)
|
72
99
|
puts "#{invalid_releases} of #{release_count} releases invalid".foreground(:yellow)
|
73
100
|
end
|
74
101
|
|
75
102
|
protected
|
76
103
|
|
104
|
+
def print_errors(release)
|
105
|
+
release.errors.each do |validation, errors|
|
106
|
+
errors.each do |error|
|
107
|
+
puts " ✕ [#{validation.to_s.humanize}] #{error}".foreground(:red)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def print_warnings(release)
|
113
|
+
release.warnings.each do |validation, warnings|
|
114
|
+
warnings.each do |warning|
|
115
|
+
puts " ✕ [#{validation.to_s.humanize}] #{warning}".foreground(:yellow)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
77
120
|
def move_release(release, destination)
|
78
121
|
target_dir = File.join(destination, release.name)
|
79
122
|
puts " ■ Moving release to #{target_dir}".foreground(:yellow)
|
@@ -27,59 +27,67 @@ class SceneToolkit::Release
|
|
27
27
|
@errors[:required_files], @warnings[:required_files] = [], []
|
28
28
|
REQUIRED_FILES.each do |ext|
|
29
29
|
file_count = send("#{ext}_files")
|
30
|
-
@errors[:required_files] << "No
|
31
|
-
@warnings[:required_files] << "Multiple
|
30
|
+
@errors[:required_files] << "No *.#{ext} files found." if file_count.none?
|
31
|
+
@warnings[:required_files] << "Multiple *.#{ext} files found." if file_count.size > 1
|
32
32
|
end
|
33
|
+
@warnings[:required_files].empty?
|
33
34
|
end
|
34
35
|
|
35
36
|
def valid_playlist?
|
36
37
|
@errors[:playlist], @warnings[:playlist] = [], []
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
if m3u_files.any?
|
39
|
+
m3u_files.each do |playlist|
|
40
|
+
File.read(playlist).split(/[\r\n]+/).each do |filename|
|
41
|
+
filename.strip!
|
42
|
+
next if filename.blank? or filename.start_with?("#") or filename.start_with?(";")
|
43
|
+
@errors[:playlist] << "File #{filename} not found" unless File.exist?(File.join(@path, filename))
|
44
|
+
end
|
44
45
|
end
|
46
|
+
else
|
47
|
+
@errors[:playlist] << "No *.m3u files found"
|
45
48
|
end
|
49
|
+
@errors[:playlist].empty?
|
46
50
|
end
|
47
51
|
|
48
52
|
def valid_checksum?
|
49
53
|
@errors[:checksum], @warnings[:checksum] = [], []
|
50
|
-
sfv = sfv_files.first
|
51
|
-
|
52
|
-
unless sfv.blank? do
|
53
|
-
files_to_check = files.inject({}) do |collection, file|
|
54
|
-
collection[File.basename(file).downcase] = File.expand_path(file)
|
55
|
-
collection
|
56
|
-
end
|
57
54
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
@warnings[:checksum] << "Possibly tampered SFV: #{line.strip}"
|
55
|
+
if sfv_files.any?
|
56
|
+
sfv_files.each do |sfv|
|
57
|
+
files_to_check = files.inject({}) do |collection, file|
|
58
|
+
collection[File.basename(file).downcase] = File.expand_path(file)
|
59
|
+
collection
|
64
60
|
end
|
65
61
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
matched_something = false
|
63
|
+
File.read(sfv).split(/[\r\n]+/).each do |line|
|
64
|
+
line.strip!
|
65
|
+
|
66
|
+
if (/(generated|raped)/i =~ line and not /MorGoTH/i =~ line)
|
67
|
+
@warnings[:checksum] << "Possibly tampered SFV: #{line.strip}"
|
68
|
+
end
|
70
69
|
|
71
|
-
if
|
72
|
-
|
73
|
-
|
70
|
+
if match = /^(.+?)\s+([\dA-Fa-f]{8})$/.match(line)
|
71
|
+
matched_something = true
|
72
|
+
filename, checksum = match.captures
|
73
|
+
filename.strip!
|
74
|
+
filename.downcase!
|
75
|
+
|
76
|
+
if files_to_check.has_key?(filename)
|
77
|
+
unless Zlib.crc32(File.read(files_to_check[filename])).eql?(checksum.hex)
|
78
|
+
@errors[:checksum] << "File #{filename} is corrupted"
|
79
|
+
end
|
80
|
+
else
|
81
|
+
@errors[:checksum] << "File #{filename} not found"
|
74
82
|
end
|
75
|
-
else
|
76
|
-
@errors[:checksum] << "File #{filename} not found (SFV)"
|
77
83
|
end
|
78
84
|
end
|
85
|
+
@warnings[:checksum] << "No files to verify found" unless matched_something
|
79
86
|
end
|
80
|
-
|
81
|
-
|
87
|
+
else
|
88
|
+
@errors[:checksum] << "No *.sfv files found"
|
82
89
|
end
|
90
|
+
@errors[:checksum].empty?
|
83
91
|
end
|
84
92
|
|
85
93
|
def valid_name?
|
@@ -87,6 +95,7 @@ class SceneToolkit::Release
|
|
87
95
|
@errors[:name] << "Release name is not a valid scene release name" unless @name =~ /^([A-Z0-9\-_.()&]+)\-(\d{4}|\d{3}x|\d{2}xx)\-([A-Z0-9_]+)$/i
|
88
96
|
@errors[:name] << "Release name is lowercased" if @name.eql?(@name.downcase)
|
89
97
|
@errors[:name] << "Release name is uppercased" if @name.eql?(@name.upcase)
|
98
|
+
@errors[:name].empty?
|
90
99
|
end
|
91
100
|
|
92
101
|
def files
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scene-toolkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 6
|
10
|
+
version: 0.1.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "V\xC3\xADctor Mart\xC3\xADnez"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-25 00:00:00 +02:00
|
19
19
|
default_executable: scene-toolkit
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|