scene-toolkit 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|