dexter 0.0.2
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/.gitignore +4 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +57 -0
- data/Rakefile +13 -0
- data/Readme.md +38 -0
- data/bin/dexter +15 -0
- data/dexter.gemspec +29 -0
- data/features/dexter_organises_series.feature +54 -0
- data/features/support/env.rb +1 -0
- data/lib/dexter.rb +140 -0
- data/lib/dexter/version.rb +3 -0
- data/spec/dexter_spec.rb +131 -0
- data/spec/spec_helper.rb +6 -0
- metadata +142 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use 1.9.2@dexter
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
dexter (0.0.1)
|
5
|
+
trollop
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
aruba (0.2.3)
|
11
|
+
background_process
|
12
|
+
cucumber (~> 0.9.0)
|
13
|
+
background_process (1.2)
|
14
|
+
builder (2.1.2)
|
15
|
+
cucumber (0.9.3)
|
16
|
+
builder (~> 2.1.2)
|
17
|
+
diff-lcs (~> 1.1.2)
|
18
|
+
gherkin (~> 2.2.9)
|
19
|
+
json (~> 1.4.6)
|
20
|
+
term-ansicolor (~> 1.0.5)
|
21
|
+
diff-lcs (1.1.2)
|
22
|
+
gemcutter (0.6.1)
|
23
|
+
gherkin (2.2.9)
|
24
|
+
json (~> 1.4.6)
|
25
|
+
term-ansicolor (~> 1.0.5)
|
26
|
+
git (1.2.5)
|
27
|
+
jeweler (1.4.0)
|
28
|
+
gemcutter (>= 0.1.0)
|
29
|
+
git (>= 1.2.5)
|
30
|
+
rubyforge (>= 2.0.0)
|
31
|
+
json (1.4.6)
|
32
|
+
json_pure (1.4.6)
|
33
|
+
rspec (2.0.1)
|
34
|
+
rspec-core (~> 2.0.1)
|
35
|
+
rspec-expectations (~> 2.0.1)
|
36
|
+
rspec-mocks (~> 2.0.1)
|
37
|
+
rspec-core (2.0.1)
|
38
|
+
rspec-expectations (2.0.1)
|
39
|
+
diff-lcs (>= 1.1.2)
|
40
|
+
rspec-mocks (2.0.1)
|
41
|
+
rspec-core (~> 2.0.1)
|
42
|
+
rspec-expectations (~> 2.0.1)
|
43
|
+
rubyforge (2.0.4)
|
44
|
+
json_pure (>= 1.1.7)
|
45
|
+
term-ansicolor (1.0.5)
|
46
|
+
trollop (1.16.2)
|
47
|
+
|
48
|
+
PLATFORMS
|
49
|
+
ruby
|
50
|
+
|
51
|
+
DEPENDENCIES
|
52
|
+
aruba
|
53
|
+
cucumber
|
54
|
+
dexter!
|
55
|
+
jeweler
|
56
|
+
rspec
|
57
|
+
trollop
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'cucumber/rake/task'
|
6
|
+
|
7
|
+
desc "Run the specs under spec"
|
8
|
+
RSpec::Core::RakeTask.new do |t|
|
9
|
+
end
|
10
|
+
|
11
|
+
Cucumber::Rake::Task.new(:cucumber)
|
12
|
+
|
13
|
+
task :default => :spec
|
data/Readme.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# dexter
|
2
|
+
|
3
|
+
Dexter helps you organize your tv series with well, you know... Dexterity}
|
4
|
+
|
5
|
+
It automatically detects all video files that seem like a series and moves them
|
6
|
+
into an appropriate path.
|
7
|
+
|
8
|
+
Currently in hard alpha but functional.
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
$ dexter
|
13
|
+
|
14
|
+
It organizes all the files within the current directory and its subdirectories and places them into appropriate folders
|
15
|
+
|
16
|
+
$ dexter --input <input> --output <output>
|
17
|
+
|
18
|
+
Checks all the directories and subdirectories in <input> and creates a folder structure moving the files in <output>
|
19
|
+
|
20
|
+
$ dexter --format ":name/S:season/:name S:seasonE:episode.:extension"
|
21
|
+
|
22
|
+
Moves the files using the format specified.
|
23
|
+
|
24
|
+
$ dexter --verbose false
|
25
|
+
|
26
|
+
Removes all output
|
27
|
+
|
28
|
+
## Running the tests - development only
|
29
|
+
|
30
|
+
Dexter is tested with RSpec and cucumber.
|
31
|
+
|
32
|
+
$ bundle exec rspec spec
|
33
|
+
|
34
|
+
Runs the functional tests
|
35
|
+
|
36
|
+
$ bundle exec cucumber features
|
37
|
+
|
38
|
+
Runs the integration tests
|
data/bin/dexter
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'trollop'
|
4
|
+
require 'dexter'
|
5
|
+
|
6
|
+
opts = Trollop::options do
|
7
|
+
opt :input, "Input directory", :default => "."
|
8
|
+
opt :output, "Output directory", :default => "."
|
9
|
+
opt :format, "Output directory format", :default => Dexter::Matchers::Video.output_format
|
10
|
+
opt :verbose, "Be verbose about what dexter is doing", :default => true
|
11
|
+
end
|
12
|
+
|
13
|
+
Dexter::Matchers::Video.output_format = opts[:format]
|
14
|
+
Dexter.verbose = opts[:verbose]
|
15
|
+
Dexter.organize!(opts[:input],opts[:output])
|
data/dexter.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dexter/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "dexter"
|
7
|
+
s.version = Dexter::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = "Josep Jaume Rey Peroy"
|
10
|
+
s.email = "josepjaume@gmail.com"
|
11
|
+
s.homepage = "http://github.com/josepjaume/dexter"
|
12
|
+
s.summary = %q{Dexter helps you organize your tv series with well, you know... Dexterity}
|
13
|
+
s.description = %q{Dexter helps you organize your tv series with well, you know... Dexterity}
|
14
|
+
|
15
|
+
s.rubyforge_project = "dexter"
|
16
|
+
|
17
|
+
s.add_development_dependency 'rspec'
|
18
|
+
s.add_development_dependency 'cucumber'
|
19
|
+
s.add_development_dependency 'aruba'
|
20
|
+
s.add_development_dependency 'jeweler'
|
21
|
+
|
22
|
+
s.add_runtime_dependency 'trollop'
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
27
|
+
s.default_executable = 'dexter'
|
28
|
+
s.require_paths = ["lib"]
|
29
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
Feature: Dexter organises series
|
2
|
+
|
3
|
+
In order to order my TV series in a clean and neat manner
|
4
|
+
As a great series freak
|
5
|
+
Dexter should be able to get its name and season & episode numbers and move them to its appropiate paths
|
6
|
+
|
7
|
+
@announce
|
8
|
+
Scenario: Dexter organizes only one file
|
9
|
+
Given a directory named "Downloads"
|
10
|
+
And a directory named "Downloads/mess"
|
11
|
+
And a directory named "Video"
|
12
|
+
And an empty file named "Downloads/dexter s01e09.avi"
|
13
|
+
When I run "dexter --input \"Downloads/dexter s01e09.avi\" --output Video"
|
14
|
+
Then the following directories should exist:
|
15
|
+
| Video/Dexter/S01 |
|
16
|
+
|
17
|
+
@announce
|
18
|
+
Scenario: Dexter organises using a custom format
|
19
|
+
Given a directory named "Downloads"
|
20
|
+
And a directory named "Downloads/mess"
|
21
|
+
And a directory named "Video"
|
22
|
+
And an empty file named "Downloads/dexter s01e09.avi"
|
23
|
+
When I run "dexter --input \"Downloads/dexter s01e09.avi\" --output Video --format \":name (Season :season)/:name S:seasonE:episode.:extension\""
|
24
|
+
Then the following directories should exist:
|
25
|
+
| Video/Dexter (Season 01) |
|
26
|
+
|
27
|
+
@announce
|
28
|
+
Scenario: Dexter isn't verbose
|
29
|
+
Given a directory named "Downloads"
|
30
|
+
And a directory named "Downloads/mess"
|
31
|
+
And a directory named "Video"
|
32
|
+
And an empty file named "Downloads/dexter s01e09.avi"
|
33
|
+
When I run "dexter --input \"Downloads/dexter s01e09.avi\" --output Video --verbose false"
|
34
|
+
Then the following directories should exist:
|
35
|
+
| Video/Dexter/S01 |
|
36
|
+
And the output should contain exactly ""
|
37
|
+
|
38
|
+
@announce
|
39
|
+
Scenario: Dexter organizes a whole directory
|
40
|
+
Given a directory named "Downloads"
|
41
|
+
And a directory named "Downloads/mess"
|
42
|
+
And a directory named "Video"
|
43
|
+
And an empty file named "Downloads/dexter s01e09.avi"
|
44
|
+
And an empty file named "Downloads/Fringe.1x03.HDTV.avi"
|
45
|
+
And an empty file named "Downloads/The.big.bang.theory.s01e09.avi"
|
46
|
+
And an empty file named "Downloads/mess/MY NAME IS EARL - s08e04 HDTV.avi"
|
47
|
+
And an empty file named "Downloads/Treme.S01E04.HDTV.XviD-NoTV.avi"
|
48
|
+
When I run "dexter --input Downloads --output Video"
|
49
|
+
Then the following directories should exist:
|
50
|
+
| Video/Dexter/S01 |
|
51
|
+
| Video/The Big Bang Theory/S01 |
|
52
|
+
| Video/Fringe/S01 |
|
53
|
+
| Video/My Name Is Earl/S08 |
|
54
|
+
| Video/Treme/S01 |
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'aruba'
|
data/lib/dexter.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Dexter
|
4
|
+
|
5
|
+
def self.verbose; @verbose; end
|
6
|
+
def self.verbose=(level);@verbose=level;end
|
7
|
+
|
8
|
+
def self.organize!(input_path, output_path)
|
9
|
+
|
10
|
+
if File.file?(input_path)
|
11
|
+
files = self.load_files([input_path])
|
12
|
+
else
|
13
|
+
files = self.load_from_directory(input_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
files.each do |file|
|
17
|
+
output_file = file.organize!(output_path)
|
18
|
+
puts "Organizing: \"#{file.filename}\" ~> \"#{output_file}\"" if Dexter.verbose
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.load_from_directory(path)
|
24
|
+
self.load_files self.list_all_files_within_directory(path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.load_files(files)
|
28
|
+
result = []
|
29
|
+
files.each do |file|
|
30
|
+
matchers.each do |matcher|
|
31
|
+
result << matcher.new(file) if matcher.allowed?(file)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
return result.compact
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.matchers
|
38
|
+
[Matchers::Video]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.list_all_files_within_directory(path)
|
42
|
+
expression = "#{path}/**/*.{#{Dexter.matchers.collect{|m| m::EXTENSIONS}.flatten.join(',')}}"
|
43
|
+
Dir.glob(expression)
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
module Matchers
|
48
|
+
class AbstractMatcher
|
49
|
+
|
50
|
+
EXTENSIONS = []
|
51
|
+
|
52
|
+
def self.allowed?(filename)
|
53
|
+
self::EXTENSIONS.include? File.extname(filename).gsub(/^\./,"")
|
54
|
+
end
|
55
|
+
|
56
|
+
def initialize(filename)
|
57
|
+
raise "Not an allowed format!" unless self.class.allowed?(filename)
|
58
|
+
@filename = filename
|
59
|
+
end
|
60
|
+
|
61
|
+
def organize!
|
62
|
+
raise "It's up to the subclass to implement this"
|
63
|
+
end
|
64
|
+
|
65
|
+
def extension
|
66
|
+
File.extname(@filename).gsub(/^\./,"")
|
67
|
+
end
|
68
|
+
|
69
|
+
def filename
|
70
|
+
@filename
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Video < AbstractMatcher
|
75
|
+
|
76
|
+
EXTENSIONS = ['avi', 'mkv']
|
77
|
+
|
78
|
+
def self.output_format
|
79
|
+
@output ||= ':name/S:season/:name S:seasonE:episode.:extension'
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.allowed?(filename)
|
83
|
+
if !super(filename)
|
84
|
+
return false
|
85
|
+
end
|
86
|
+
filename.downcase =~ /([0-9A-z\s\.]+)\s?\.?-?\s?\.?(s[0-9]+e[0-9]+|[0-9]+x[0-9]+).*/
|
87
|
+
return !!$1
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.output_format=(options)
|
91
|
+
@output = options
|
92
|
+
end
|
93
|
+
|
94
|
+
def name
|
95
|
+
filename.downcase =~ /([0-9A-z\s\.]+)\s?\.?-?\s?\.?(s[0-9]+e[0-9]+|[0-9]+x[0-9]+).*/
|
96
|
+
return nil if $1.nil?
|
97
|
+
return $1.gsub('.', ' ') \
|
98
|
+
.split(' ') \
|
99
|
+
.collect(&:capitalize) \
|
100
|
+
.join(' ') \
|
101
|
+
.strip
|
102
|
+
end
|
103
|
+
|
104
|
+
def season
|
105
|
+
filename.downcase =~ /[\s\.]?s([0-9]{2})e[0-9]{2}/
|
106
|
+
filename.downcase =~ /[\s\.]?([0-9]+)x[0-9]+/ if $1.nil?
|
107
|
+
return nil if $1.nil?
|
108
|
+
$1.to_i
|
109
|
+
end
|
110
|
+
|
111
|
+
def episode
|
112
|
+
filename.downcase =~ /[\s\.]?s[0-9]{2}e([0-9]{2})/
|
113
|
+
filename.downcase =~ /[\s\.]?[0-9]+x([0-9]+)/ if $1.nil?
|
114
|
+
return nil if $1.nil?
|
115
|
+
$1.to_i
|
116
|
+
end
|
117
|
+
|
118
|
+
def output(path)
|
119
|
+
options = {
|
120
|
+
:season => season.to_s.rjust(2,'0'),
|
121
|
+
:episode => episode.to_s.rjust(2,'0'),
|
122
|
+
:name => name,
|
123
|
+
:path => path,
|
124
|
+
:extension => extension
|
125
|
+
}
|
126
|
+
options.inject(':path/' + self.class.output_format){ |output, object|
|
127
|
+
output = (output.gsub(":#{object[0]}", object[1]) || output)
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
131
|
+
def organize!(path)
|
132
|
+
output_path = File.dirname(output(path))
|
133
|
+
FileUtils.mkdir_p(output_path)
|
134
|
+
FileUtils.mv(@filename, output(path))
|
135
|
+
return output(path)
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
data/spec/dexter_spec.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'dexter'
|
3
|
+
|
4
|
+
describe Dexter do
|
5
|
+
describe 'self.load_files' do
|
6
|
+
it "creates several instances of Video from an array" do
|
7
|
+
list = [
|
8
|
+
"dexter s01e02 HDTV.avi",
|
9
|
+
"the.big.bang.theory.1x12.mkv",
|
10
|
+
"the.big.bang.theory.1x12.sub",
|
11
|
+
"the.big.bang.theory.1x12.srt"
|
12
|
+
]
|
13
|
+
Dexter::Matchers::Video.should_receive(:new).exactly(2).times
|
14
|
+
subject.load_files(list)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'self.organize!' do
|
19
|
+
it "organizes all the files within a directory and subdirectories" do
|
20
|
+
videos = (1..3).collect{Dexter::Matchers::Video.new('dexter s01e01.avi')}
|
21
|
+
videos.each { |video|
|
22
|
+
video.should_receive(:organize!).exactly(1).times
|
23
|
+
}
|
24
|
+
Dexter.should_receive(:load_from_directory)\
|
25
|
+
.and_return(videos)
|
26
|
+
|
27
|
+
File.should_receive(:file?).times.and_return(false)
|
28
|
+
|
29
|
+
Dexter.organize!('.', '.')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'self.load_from_directory' do
|
34
|
+
it "creates an instance of the corresponding type from every file" do
|
35
|
+
Dexter.should_receive(:list_all_files_within_directory)\
|
36
|
+
.and_return(["../family guy s04e08.avi","../fringe 1x18.mkv"])
|
37
|
+
Dexter.load_from_directory('.').should have(2).videos
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'self.list_all_files_within_directory' do
|
42
|
+
it "gets a list of all files in a directory recursively" do
|
43
|
+
Dir.should_receive(:glob).and_return(["../dexter s01e02 HDTV.avi", "../modern family 1x02.mkv"])
|
44
|
+
Dexter.list_all_files_within_directory('/home/josepjaume').should == ["../dexter s01e02 HDTV.avi", "../modern family 1x02.mkv"]
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
describe Dexter::Matchers do
|
50
|
+
describe Dexter::Matchers::Video do
|
51
|
+
subject{Dexter::Matchers::Video}
|
52
|
+
describe 'self.allowed?' do
|
53
|
+
it "returns true if the file is allowed" do
|
54
|
+
subject.allowed?('dexter s01e01.avi').should be_true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'extension' do
|
59
|
+
it "sorts the extension of a file out" do
|
60
|
+
video = subject.new('dexter s01e01.avi')
|
61
|
+
video.extension.should == 'avi'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'name' do
|
66
|
+
it "returns the name of the tv series given a particular filename" do
|
67
|
+
examples = {
|
68
|
+
'the big bang theory - s01e09.avi' => 'The Big Bang Theory',
|
69
|
+
'DEXTER S01E09.avi' => 'Dexter',
|
70
|
+
'Family.Guy.S10E08.avi' => 'Family Guy'
|
71
|
+
}
|
72
|
+
examples.each do |key,value|
|
73
|
+
video = subject.new('dexter s01e01.avi')
|
74
|
+
video.stub(:filename).and_return(key)
|
75
|
+
video.name.should == value
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
describe 'season' do
|
80
|
+
it "returns the season when given a particular filename" do
|
81
|
+
examples = {
|
82
|
+
'the big bang theory - s01e09.avi' => 1,
|
83
|
+
'DEXTER S05E09.avi' => 5,
|
84
|
+
'Family.Guy.S10E08.avi' => 10,
|
85
|
+
'The Show of cleveland - 1x2 .mkv' => 1
|
86
|
+
}
|
87
|
+
examples.each do |key,value|
|
88
|
+
video = subject.new('dexter s01e01.avi')
|
89
|
+
video.stub(:filename).and_return(key)
|
90
|
+
video.season.should == value
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
describe 'episode' do
|
95
|
+
it "returns the episode when given a particular filename" do
|
96
|
+
examples = {
|
97
|
+
'the big bang theory - s01e09.avi' => 9,
|
98
|
+
'DEXTER S05E27.avi' => 27,
|
99
|
+
'Family.Guy.S10E08.avi' => 8,
|
100
|
+
'The Show of cleveland - 1x2 .mkv' => 2
|
101
|
+
}
|
102
|
+
examples.each do |key,value|
|
103
|
+
video = subject.new('dexter s01e01.avi')
|
104
|
+
video.stub(:filename).and_return(key)
|
105
|
+
video.episode.should == value
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
describe "output" do
|
110
|
+
it "should return the output path of the video" do
|
111
|
+
video = Dexter::Matchers::Video.new('dexter s01e01.avi')
|
112
|
+
video.should_receive(:season).and_return(1)
|
113
|
+
video.should_receive(:episode).and_return(2)
|
114
|
+
video.should_receive(:name).and_return("Modern Family")
|
115
|
+
video.should_receive(:extension).and_return('avi')
|
116
|
+
video.output(".").should == "./Modern Family/S01/Modern Family S01E02.avi"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
describe :organize! do
|
120
|
+
it "should move the video to its corresponding path" do
|
121
|
+
video = Dexter::Matchers::Video.new('dexter s01e01.avi')
|
122
|
+
video.stub(:output).and_return('./Modern Family/S01/Modern Family S01E02.avi')
|
123
|
+
video.stub(:filename).and_return('dexter s01e01.avi')
|
124
|
+
FileUtils.should_receive(:mkdir_p).with('./Modern Family/S01')
|
125
|
+
FileUtils.should_receive(:mv).with('dexter s01e01.avi','./Modern Family/S01/Modern Family S01E02.avi')
|
126
|
+
video.organize!('./')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dexter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Josep Jaume Rey Peroy
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-10-29 00:00:00 +02:00
|
18
|
+
default_executable: dexter
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :development
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: cucumber
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :development
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: aruba
|
48
|
+
prerelease: false
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id003
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: jeweler
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
type: :development
|
71
|
+
version_requirements: *id004
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: trollop
|
74
|
+
prerelease: false
|
75
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
type: :runtime
|
84
|
+
version_requirements: *id005
|
85
|
+
description: Dexter helps you organize your tv series with well, you know... Dexterity
|
86
|
+
email: josepjaume@gmail.com
|
87
|
+
executables:
|
88
|
+
- dexter
|
89
|
+
extensions: []
|
90
|
+
|
91
|
+
extra_rdoc_files: []
|
92
|
+
|
93
|
+
files:
|
94
|
+
- .gitignore
|
95
|
+
- .rspec
|
96
|
+
- .rvmrc
|
97
|
+
- Gemfile
|
98
|
+
- Gemfile.lock
|
99
|
+
- Rakefile
|
100
|
+
- Readme.md
|
101
|
+
- bin/dexter
|
102
|
+
- dexter.gemspec
|
103
|
+
- features/dexter_organises_series.feature
|
104
|
+
- features/support/env.rb
|
105
|
+
- lib/dexter.rb
|
106
|
+
- lib/dexter/version.rb
|
107
|
+
- spec/dexter_spec.rb
|
108
|
+
- spec/spec_helper.rb
|
109
|
+
has_rdoc: true
|
110
|
+
homepage: http://github.com/josepjaume/dexter
|
111
|
+
licenses: []
|
112
|
+
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
segments:
|
124
|
+
- 0
|
125
|
+
version: "0"
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
version: "0"
|
134
|
+
requirements: []
|
135
|
+
|
136
|
+
rubyforge_project: dexter
|
137
|
+
rubygems_version: 1.3.7
|
138
|
+
signing_key:
|
139
|
+
specification_version: 3
|
140
|
+
summary: Dexter helps you organize your tv series with well, you know... Dexterity
|
141
|
+
test_files: []
|
142
|
+
|