scene-toolkit 0.2.6 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +12 -9
- data/bin/scene-toolkit +1 -1
- data/lib/scene_toolkit/cli/auto_rename.rb +18 -12
- data/lib/scene_toolkit/cli/helpers.rb +4 -8
- data/lib/scene_toolkit/cli/playlists.rb +2 -8
- data/lib/scene_toolkit/cli/verify.rb +6 -5
- data/lib/scene_toolkit/release/validations/checksum.rb +26 -17
- data/lib/scene_toolkit/release/validations/files.rb +12 -7
- data/lib/scene_toolkit/release/validations/name.rb +4 -6
- data/lib/scene_toolkit/release/validations/playlist.rb +9 -12
- data/lib/scene_toolkit/release/validations.rb +30 -7
- data/lib/scene_toolkit/release.rb +23 -8
- data/lib/scene_toolkit.rb +1 -1
- data/scene-toolkit.gemspec +2 -1
- metadata +57 -15
data/Gemfile.lock
CHANGED
@@ -1,24 +1,27 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
scene-toolkit (0.2.
|
5
|
-
|
4
|
+
scene-toolkit (0.2.6)
|
5
|
+
active_support (>= 3.0.0)
|
6
6
|
colored
|
7
7
|
i18n
|
8
8
|
nestful
|
9
|
+
nokogiri
|
9
10
|
optitron
|
10
11
|
|
11
12
|
GEM
|
12
13
|
remote: http://rubygems.org/
|
13
14
|
specs:
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
active_support (3.0.0)
|
16
|
+
activesupport (= 3.0.0)
|
17
|
+
activesupport (3.0.0)
|
18
|
+
callsite (0.0.11)
|
17
19
|
colored (1.2)
|
18
20
|
i18n (0.6.0)
|
19
|
-
nestful (0.0.
|
21
|
+
nestful (0.0.8)
|
20
22
|
activesupport (>= 3.0.0.beta)
|
21
|
-
|
23
|
+
nokogiri (1.5.0)
|
24
|
+
optitron (0.3.3)
|
22
25
|
callsite (~> 0.0.4)
|
23
26
|
parameters_extra (~> 0.2.0)
|
24
27
|
parameters_extra (0.2.0)
|
@@ -28,9 +31,9 @@ GEM
|
|
28
31
|
ruby2ruby (1.2.5)
|
29
32
|
ruby_parser (~> 2.0)
|
30
33
|
sexp_processor (~> 3.0)
|
31
|
-
ruby_parser (2.
|
34
|
+
ruby_parser (2.3.1)
|
32
35
|
sexp_processor (~> 3.0)
|
33
|
-
sexp_processor (3.0.
|
36
|
+
sexp_processor (3.0.10)
|
34
37
|
|
35
38
|
PLATFORMS
|
36
39
|
ruby
|
data/bin/scene-toolkit
CHANGED
@@ -1,23 +1,26 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'nestful'
|
4
|
+
require 'nokogiri'
|
4
5
|
require 'scene_toolkit/ext'
|
5
6
|
|
6
7
|
module SceneToolkit
|
7
8
|
class CLI < Optitron::CLI
|
8
9
|
class GoogleMatcher
|
9
10
|
def self.match(name)
|
10
|
-
|
11
|
-
response =
|
12
|
-
response.scan(regex).uniq.reject(&:downcase?)
|
13
|
-
end
|
14
|
-
end
|
11
|
+
response = Nestful.get("http://www.google.com/search", :params => {:q => name, :num => 100})
|
12
|
+
response = Nokogiri::HTML(response).search(".g").text.encode("utf-8", "utf-8", :invalid => :replace)
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
if name =~ /[\d+]$/ # artist-ablum-2012
|
15
|
+
regex = /#{Regexp.escape(name)}(?:-[A-Za-z0-9]+)*/i
|
16
|
+
matches = response.scan(regex).reject(&:downcase?).reject { |m| m.size == name.size }.uniq
|
17
|
+
|
18
|
+
else # artist-ablum-2012-group
|
19
|
+
regex = /#{Regexp.escape(name)}/i
|
20
|
+
matches = response.scan(regex).reject(&:downcase?).select { |m| m.size == name.size }.uniq
|
21
|
+
end
|
22
|
+
|
23
|
+
matches.reject { |m| m == name }.select { |m| m =~ Release::Validations::Name::REGEXP }
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
@@ -36,7 +39,8 @@ module SceneToolkit
|
|
36
39
|
next if release_name.blank?
|
37
40
|
|
38
41
|
match = nil
|
39
|
-
[
|
42
|
+
matches = []
|
43
|
+
[GoogleMatcher].each do |matcher|
|
40
44
|
matches = matcher.match(release_name)
|
41
45
|
if matches.one?
|
42
46
|
match = matches.first
|
@@ -47,8 +51,10 @@ module SceneToolkit
|
|
47
51
|
if match.present?
|
48
52
|
heading(release, :green) { info "Renamed #{release.name} => #{match}" }
|
49
53
|
release.rename!(match)
|
54
|
+
elsif matches.any?
|
55
|
+
heading(release, :red) { error (["Multiple matches found for #{release_name}:"] + matches).join("\r\n * ") }
|
50
56
|
else
|
51
|
-
heading(release, :red) { error "No matches found for #{
|
57
|
+
heading(release, :red) { error "No matches found for #{release_name}" }
|
52
58
|
end
|
53
59
|
end
|
54
60
|
end
|
@@ -26,18 +26,14 @@ module SceneToolkit
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def print_errors(release)
|
29
|
-
release.errors.each do |
|
30
|
-
|
31
|
-
warn "[#{validation.to_s.humanize}] #{error}"
|
32
|
-
end
|
29
|
+
release.errors.uniq.each do |message|
|
30
|
+
error(message)
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
36
34
|
def print_warnings(release)
|
37
|
-
release.warnings.each do |
|
38
|
-
|
39
|
-
warn "[#{validation.to_s.humanize}] #{warning}"
|
40
|
-
end
|
35
|
+
release.warnings.each do |message|
|
36
|
+
warn(message)
|
41
37
|
end
|
42
38
|
end
|
43
39
|
|
@@ -15,15 +15,9 @@ module SceneToolkit
|
|
15
15
|
heading(release, :green) do
|
16
16
|
print_errors(release)
|
17
17
|
|
18
|
-
|
19
|
-
if candidates.none?
|
20
|
-
error "Unable to guess playlist filename"
|
21
|
-
next
|
22
|
-
end
|
23
|
-
|
24
|
-
playlist_filename = [candidates.max { |k, v| v.size }.first, ".m3u"].join
|
25
|
-
|
18
|
+
playlist_filename = release.heuristic_filename("m3u")
|
26
19
|
playlist_path = File.join(release.path, playlist_filename)
|
20
|
+
|
27
21
|
if File.exist?(playlist_path) and not params["force"]
|
28
22
|
error "Playlist #{playlist_filename} already exists. Use --force to replace it."
|
29
23
|
else
|
@@ -10,25 +10,26 @@ module SceneToolkit
|
|
10
10
|
opt "ignore-filename-case", "Ignore case when validating SFV/M3U filenames"
|
11
11
|
opt "move-invalid-to", "Move INVALID releases to specified folder", :type => :string
|
12
12
|
opt "move-valid-to", "Move VALID releases to specified folder", :type => :string
|
13
|
+
opt "repository", "Directory to look up in order to resolve missing files", :type => :string
|
13
14
|
|
14
15
|
def verify(directory_string)
|
15
16
|
validations_to_exec = []
|
16
|
-
SceneToolkit::Release.available_validations.
|
17
|
+
SceneToolkit::Release.available_validations.each do |name|
|
17
18
|
validations_to_exec << name if params.delete(name).eql?(true)
|
18
19
|
end
|
19
20
|
|
20
21
|
if validations_to_exec.none?
|
21
|
-
validations_to_exec = SceneToolkit::Release::available_validations
|
22
|
+
validations_to_exec = SceneToolkit::Release::available_validations
|
22
23
|
end
|
23
24
|
|
24
25
|
invalid_target_directory = params.delete("move-invalid-to")
|
25
26
|
unless invalid_target_directory.nil?
|
26
|
-
raise ArgumentError.new("#{invalid_target_directory} does not exist") unless File.directory?(invalid_target_directory)
|
27
|
+
raise ArgumentError.new("#{invalid_target_directory.inspect} does not exist") unless File.directory?(invalid_target_directory)
|
27
28
|
end
|
28
29
|
|
29
30
|
valid_target_directory = params.delete("move-valid-to")
|
30
31
|
unless valid_target_directory.nil?
|
31
|
-
raise ArgumentError.new("#{
|
32
|
+
raise ArgumentError.new("#{valid_target_directory.inspect} does not exist") unless File.directory?(valid_target_directory)
|
32
33
|
end
|
33
34
|
|
34
35
|
release_count = 0
|
@@ -37,7 +38,7 @@ module SceneToolkit
|
|
37
38
|
|
38
39
|
each_release(directory_string) do |release|
|
39
40
|
release_count += 1
|
40
|
-
if release.valid?(validations_to_exec,
|
41
|
+
if release.valid?(validations_to_exec, params)
|
41
42
|
valid_releases += 1
|
42
43
|
if not params["hide-valid"] or not valid_target_directory.nil?
|
43
44
|
heading(release, :green) do
|
@@ -9,54 +9,63 @@ module SceneToolkit
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def valid_checksum?(params = {})
|
12
|
-
|
12
|
+
recover_file!(self.heuristic_filename("sfv"), params["repository"]) if params["repository"] and sfv_files.none?
|
13
|
+
|
13
14
|
if sfv_files.any?
|
14
15
|
sfv_files.each do |sfv|
|
15
16
|
begin
|
16
|
-
validate_checksum(sfv)
|
17
|
+
validate_checksum(sfv, params)
|
17
18
|
rescue => e
|
18
|
-
@errors
|
19
|
+
@errors << e.message
|
19
20
|
end
|
20
21
|
end
|
21
22
|
else
|
22
|
-
|
23
|
+
file_not_found!(self.heuristic_filename("sfv"))
|
23
24
|
end
|
24
|
-
|
25
|
+
|
26
|
+
@errors.none?
|
25
27
|
end
|
26
28
|
|
27
29
|
protected
|
28
30
|
|
29
|
-
def validate_checksum(sfv)
|
30
|
-
|
31
|
+
def validate_checksum(sfv, params)
|
32
|
+
filenames = files.each_with_object({}) do |file, collection|
|
31
33
|
collection[File.basename(file).downcase] = File.expand_path(file)
|
32
|
-
collection
|
33
34
|
end
|
34
35
|
|
35
|
-
|
36
|
+
filename_match = false
|
36
37
|
File.read(sfv, :mode => "rb").split(/[\r\n]+/).each do |line|
|
37
38
|
line.strip!
|
38
39
|
|
39
40
|
if (/(generated|raped)/i =~ line and not /MorGoTH/i =~ line)
|
40
|
-
@warnings
|
41
|
+
@warnings << "Possibly tampered SFV: #{line.strip}"
|
41
42
|
end
|
42
43
|
|
43
44
|
if match = /^(.+?)\s+([\dA-Fa-f]{8})$/.match(line)
|
44
|
-
|
45
|
+
filename_match = true
|
45
46
|
filename, checksum = match.captures
|
46
47
|
filename.strip!
|
47
48
|
next if filename.blank? or filename.start_with?("#") or filename.start_with?(";")
|
48
49
|
filename.downcase!
|
49
50
|
|
50
|
-
if
|
51
|
-
|
52
|
-
|
51
|
+
if params["repository"] and not filenames.has_key?(filename)
|
52
|
+
recover_file!(filename, params["repository"])
|
53
|
+
filenames = files.each_with_object({}) do |file, collection|
|
54
|
+
collection[File.basename(file).downcase] = File.expand_path(file)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
if filenames.has_key?(filename)
|
59
|
+
unless Zlib.crc32(File.read(filenames[filename])).eql?(checksum.hex)
|
60
|
+
recover_file!(File.basename(filenames[filename]), params["repository"], false) if params["repository"]
|
61
|
+
unless Zlib.crc32(File.read(filenames[filename])).eql?(checksum.hex)
|
62
|
+
@errors << "File #{filename.inspect} is corrupted. (#{filename.to_search_string})"
|
63
|
+
end
|
53
64
|
end
|
54
|
-
else
|
55
|
-
@errors[:checksum] << "File #{filename} not found"
|
56
65
|
end
|
57
66
|
end
|
58
67
|
end
|
59
|
-
@
|
68
|
+
@errors << "No files to verify found" unless filename_match
|
60
69
|
end
|
61
70
|
end
|
62
71
|
end
|
@@ -2,20 +2,25 @@ module SceneToolkit
|
|
2
2
|
class Release
|
3
3
|
module Validations
|
4
4
|
module Files
|
5
|
-
|
5
|
+
REQUIRED_FILES_EXT = [:sfv, :nfo, :m3u]
|
6
6
|
|
7
7
|
def self.included(base)
|
8
8
|
base.register_validation(:files, "Validate inclusion of required files")
|
9
9
|
end
|
10
10
|
|
11
11
|
def valid_files?(params = {})
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
REQUIRED_FILES_EXT.each do |ext|
|
13
|
+
if params["repository"] and not File.exists?(File.join(self.path, self.heuristic_filename(ext)))
|
14
|
+
recover_file!(self.heuristic_filename(ext), params["repository"])
|
15
|
+
end
|
16
|
+
|
17
|
+
required_files = send("#{ext}_files")
|
18
|
+
|
19
|
+
file_not_found!(self.heuristic_filename(ext)) if required_files.none?
|
20
|
+
|
21
|
+
@warnings << "Multiple *.#{ext} files found." if required_files.size > 1
|
17
22
|
end
|
18
|
-
@
|
23
|
+
@errors.none?
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
@@ -2,19 +2,17 @@ module SceneToolkit
|
|
2
2
|
class Release
|
3
3
|
module Validations
|
4
4
|
module Name
|
5
|
-
REGEXP = /^([A-Z0-9
|
5
|
+
REGEXP = /^([A-Z0-9\-\_\.\(\)\&]+)\-(\d{4}|\d{3}x|\d{2}xx)\-([A-Z0-9\_\-]+)$/i
|
6
6
|
|
7
7
|
def self.included(base)
|
8
8
|
base.register_validation(:name, "Validate release name")
|
9
9
|
end
|
10
10
|
|
11
11
|
def valid_name?(params = {})
|
12
|
-
@errors
|
12
|
+
@errors << "#{@name.inspect} is not a valid scene release name" unless @name =~ REGEXP
|
13
|
+
@errors << "#{@name.inspect} is lowercased" if @name.eql?(@name.downcase)
|
13
14
|
|
14
|
-
@errors
|
15
|
-
@errors[:name] << "Release name is lowercased" if @name.eql?(@name.downcase)
|
16
|
-
@errors[:name] << "Release name is uppercased" if @name.eql?(@name.upcase)
|
17
|
-
@errors[:name].empty?
|
15
|
+
@errors.none?
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
@@ -7,21 +7,22 @@ module SceneToolkit
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def valid_playlist?(params = {})
|
10
|
-
|
10
|
+
recover_file!(self.heuristic_filename("m3u"), params["repository"]) if params["repository"] and m3u_files.none?
|
11
|
+
|
11
12
|
if m3u_files.any?
|
12
13
|
m3u_files.each do |playlist|
|
13
14
|
begin
|
14
|
-
validate_playlist(playlist, params[
|
15
|
+
validate_playlist(playlist, params["case-sensitive"])
|
15
16
|
rescue => e
|
16
|
-
@errors
|
17
|
+
@errors << e.message
|
17
18
|
end
|
18
19
|
end
|
19
20
|
else
|
20
|
-
|
21
|
+
file_not_found!(self.heuristic_filename("m3u"))
|
21
22
|
end
|
22
|
-
@errors[:playlist].empty?
|
23
|
-
end
|
24
23
|
|
24
|
+
@errors.none?
|
25
|
+
end
|
25
26
|
|
26
27
|
protected
|
27
28
|
|
@@ -30,16 +31,12 @@ module SceneToolkit
|
|
30
31
|
filename.strip!
|
31
32
|
next if filename.blank? or filename.start_with?("#") or filename.start_with?(";")
|
32
33
|
if case_sensitive
|
33
|
-
file_not_found(filename) unless File.exist?(File.join(@path, filename))
|
34
|
+
file_not_found!(filename) unless File.exist?(File.join(@path, filename))
|
34
35
|
else
|
35
|
-
file_not_found(filename) unless files.select { |file| file.downcase == File.join(@path, filename).downcase }.any?
|
36
|
+
file_not_found!(filename) unless files.select { |file| file.downcase == File.join(@path, filename).downcase }.any?
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
39
|
-
|
40
|
-
def file_not_found(filename)
|
41
|
-
@errors[:playlist] << "File #{filename} not found"
|
42
|
-
end
|
43
40
|
end
|
44
41
|
end
|
45
42
|
end
|
@@ -1,25 +1,48 @@
|
|
1
|
-
require 'active_support/
|
2
|
-
require "active_support/core_ext/class/attribute_accessors"
|
1
|
+
require 'active_support/all'
|
3
2
|
|
4
3
|
module SceneToolkit
|
5
4
|
class Release
|
6
5
|
module Validations
|
7
6
|
extend ActiveSupport::Concern
|
8
7
|
|
9
|
-
def valid?(validations_to_exec = @available_validations, params = {
|
10
|
-
@errors, @warnings = { }, { }
|
8
|
+
def valid?(validations_to_exec = @available_validations, params = {})
|
11
9
|
validations_to_exec.each do |name|
|
12
10
|
send("valid_#{name}?", params)
|
13
11
|
end
|
14
|
-
@errors.
|
12
|
+
@errors.none?
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def recover_file!(filename, repository, warn = true)
|
18
|
+
if repository_file = lookup_file(filename, repository)
|
19
|
+
target_file = File.join(self.path, filename)
|
20
|
+
|
21
|
+
unless File.expand_path(target_file) == File.expand_path(repository_file)
|
22
|
+
@warnings << " * File #{filename.inspect} recovered from #{File.dirname(repository_file).inspect}"
|
23
|
+
|
24
|
+
File.delete(target_file) if File.exists?(target_file)
|
25
|
+
FileUtils.mv(repository_file, target_file)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
file_not_found!(filename)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def lookup_file(filename, repository)
|
33
|
+
Dir.glob(File.join(Shellwords.shellescape(repository), "**", Shellwords.shellescape(filename))).first
|
34
|
+
end
|
35
|
+
|
36
|
+
def file_not_found!(filename)
|
37
|
+
@errors << "File #{filename.inspect} not found. (#{filename.to_search_string})"
|
15
38
|
end
|
16
39
|
|
17
40
|
included do
|
18
41
|
cattr_accessor :available_validations
|
19
|
-
@@available_validations =
|
42
|
+
@@available_validations = []
|
20
43
|
|
21
44
|
def self.register_validation(name, description)
|
22
|
-
@@available_validations
|
45
|
+
@@available_validations << name
|
23
46
|
end
|
24
47
|
end
|
25
48
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'scene_toolkit/release/helpers'
|
2
2
|
require 'scene_toolkit/release/auto_rename'
|
3
3
|
require 'scene_toolkit/release/validations'
|
4
|
-
require 'scene_toolkit/release/validations/checksum'
|
5
4
|
require 'scene_toolkit/release/validations/name'
|
6
|
-
require 'scene_toolkit/release/validations/playlist'
|
7
5
|
require 'scene_toolkit/release/validations/files'
|
6
|
+
require 'scene_toolkit/release/validations/playlist'
|
7
|
+
require 'scene_toolkit/release/validations/checksum'
|
8
8
|
|
9
9
|
module SceneToolkit
|
10
10
|
class Release
|
@@ -15,23 +15,38 @@ module SceneToolkit
|
|
15
15
|
include AutoRename
|
16
16
|
include Helpers
|
17
17
|
|
18
|
-
include Validations::Checksum
|
19
18
|
include Validations::Name
|
20
|
-
include Validations::Playlist
|
21
19
|
include Validations::Files
|
20
|
+
include Validations::Playlist
|
21
|
+
include Validations::Checksum
|
22
22
|
|
23
23
|
def initialize(path)
|
24
24
|
@path = File.expand_path(path)
|
25
25
|
@name = File.basename(path)
|
26
|
-
@errors, @warnings =
|
26
|
+
@errors, @warnings = [], []
|
27
27
|
end
|
28
28
|
|
29
29
|
def heuristic_name
|
30
|
-
|
31
|
-
candidates = files.group_by { |name| name }.max { |a, b| a.last.size <=> b.last.size }
|
32
|
-
if candidates
|
30
|
+
if candidates = common_filenames
|
33
31
|
candidates.first.gsub(/^\d+[-_]/, "")
|
32
|
+
else
|
33
|
+
self.name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def heuristic_filename(ext)
|
38
|
+
if candidates = common_filenames
|
39
|
+
"#{candidates.first}.#{ext}"
|
40
|
+
else
|
41
|
+
"00-#{self.name.downcase}.#{ext}"
|
34
42
|
end
|
35
43
|
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def common_filenames
|
48
|
+
files = (m3u_files + nfo_files + sfv_files).map { |f| File.basename(f, ".*") }
|
49
|
+
files.group_by { |name| name }.max { |a, b| a.last.size <=> b.last.size }
|
50
|
+
end
|
36
51
|
end
|
37
52
|
end
|
data/lib/scene_toolkit.rb
CHANGED
data/scene-toolkit.gemspec
CHANGED
@@ -14,10 +14,11 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
15
|
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
16
16
|
|
17
|
-
s.add_dependency("
|
17
|
+
s.add_dependency("active_support", [">= 3.0.0"])
|
18
18
|
s.add_dependency("i18n")
|
19
19
|
s.add_dependency("colored")
|
20
20
|
s.add_dependency("optitron")
|
21
21
|
s.add_dependency("nestful")
|
22
|
+
s.add_dependency("nokogiri")
|
22
23
|
end
|
23
24
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scene-toolkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,27 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-09-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement:
|
15
|
+
name: active_support
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: 3.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.0.0
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: i18n
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: colored
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: optitron
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: nestful
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,7 +85,28 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :runtime
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: nokogiri
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
69
110
|
description: Tool to assist scene MP3 library maintenance
|
70
111
|
email:
|
71
112
|
- knoopx@gmail.com
|
@@ -118,8 +159,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
159
|
version: '0'
|
119
160
|
requirements: []
|
120
161
|
rubyforge_project:
|
121
|
-
rubygems_version: 1.8.
|
162
|
+
rubygems_version: 1.8.24
|
122
163
|
signing_key:
|
123
164
|
specification_version: 3
|
124
165
|
summary: Tool to assist scene MP3 library maintenance
|
125
166
|
test_files: []
|
167
|
+
has_rdoc:
|