torganiser 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/torganiser/episode_file.rb +47 -13
- data/lib/torganiser/scanner.rb +0 -1
- data/lib/torganiser/version.rb +1 -1
- data/spec/torganiser/episode_file_spec.rb +105 -2
- data/spec/torganiser/scanner_spec.rb +1 -1
- data/torganiser.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa62b57bdb8c2d67d0068a7c999f21bbd0d5cd13
|
4
|
+
data.tar.gz: 876710a0c443c89d88ecc420133d1687c44b2ab1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6488c31821632f93787d9e1e2a25e3aa0bc0e2f8b0531b55677991a29577a2e215e8acdf2accb1561ffc1e9ee1e2ad76372ef2725ad6d98c8aa072d21ff3d4a7
|
7
|
+
data.tar.gz: 4d89ba9e9a1a12944a8f21c775880273e5315028bd6702cd36d34d930802fdee939961af758d399aa900be0b43a087da1da4a0bcc4f7734ef195b53a1cf9f911
|
data/README.md
CHANGED
@@ -5,15 +5,6 @@ module Torganiser
|
|
5
5
|
|
6
6
|
attr_reader :file
|
7
7
|
|
8
|
-
EPISODE_INFO_MATCHER = %r{^
|
9
|
-
(?<series>.+) # Series name, and possibly year
|
10
|
-
.s(?<season>\d+) # season number
|
11
|
-
e(?<episode>\d+) # episode number
|
12
|
-
\..*$ # everything else
|
13
|
-
}ix
|
14
|
-
|
15
|
-
YEAR_MATCHER = /^\d{4}$/
|
16
|
-
|
17
8
|
def initialize(file)
|
18
9
|
@file = file
|
19
10
|
end
|
@@ -32,16 +23,59 @@ module Torganiser
|
|
32
23
|
|
33
24
|
def series
|
34
25
|
@series ||= begin
|
35
|
-
|
36
|
-
|
37
|
-
Series.new(parts.join(' '), year:year)
|
26
|
+
year = year.to_i if year = episode_info[:year]
|
27
|
+
Series.new(series_name, year: year)
|
38
28
|
end
|
39
29
|
end
|
40
30
|
|
41
31
|
private
|
42
32
|
|
33
|
+
def series_name
|
34
|
+
episode_info[:name].split('.').join(' ').gsub(/[^a-z]+$/i, '')
|
35
|
+
end
|
36
|
+
|
43
37
|
def episode_info
|
44
|
-
@episode_info ||=
|
38
|
+
@episode_info ||= Matcher.match(basename) or raise(
|
39
|
+
"Unable to parse #{file}"
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
# A matcher that can extract semantic information from a
|
44
|
+
# properly named file.
|
45
|
+
module Matcher
|
46
|
+
separator = '(\.|\s|\s?\-\s?)'
|
47
|
+
|
48
|
+
long_format = [
|
49
|
+
's(?<season>\d+)', # season number
|
50
|
+
'e(?<episode>\d+)', # episode number
|
51
|
+
'(e\d+)?' # optional second episode number, ignored
|
52
|
+
].join('\s?') # optionally space separated
|
53
|
+
|
54
|
+
# season number and episode number together, optionally with an 'x'
|
55
|
+
short_format = '\[?(?<season>\d+)x?(?<episode>\d{2})\]?'
|
56
|
+
|
57
|
+
# specials don't fit nicely into the season/episode model.
|
58
|
+
special = "s(?<season>0)(?<episode>0)|s(?<season>\\d+)#{separator}special"
|
59
|
+
|
60
|
+
season_info = "(#{long_format}|#{short_format}|#{special})"
|
61
|
+
|
62
|
+
# Series name, and possibly year
|
63
|
+
series_with_year = '(?<name>.*)\.(?<year>\d{4})'
|
64
|
+
series_without_year = '(?<name>.*)'
|
65
|
+
|
66
|
+
# Series without year takes precedence
|
67
|
+
series = "(#{series_with_year}|#{series_without_year})"
|
68
|
+
|
69
|
+
PATTERN = %r{^
|
70
|
+
#{series} # Series name, and possibly year
|
71
|
+
#{separator}#{season_info} # season info
|
72
|
+
#{separator}.*$ # stuff we don't care about
|
73
|
+
}ix
|
74
|
+
|
75
|
+
def self.match basename
|
76
|
+
PATTERN.match basename
|
77
|
+
end
|
78
|
+
|
45
79
|
end
|
46
80
|
|
47
81
|
end
|
data/lib/torganiser/scanner.rb
CHANGED
data/lib/torganiser/version.rb
CHANGED
@@ -4,12 +4,12 @@ module Torganiser
|
|
4
4
|
|
5
5
|
describe EpisodeFile do
|
6
6
|
|
7
|
+
subject { EpisodeFile.new(file) }
|
8
|
+
|
7
9
|
context "when initialized with an informative filename" do
|
8
10
|
|
9
11
|
let(:file) { "file/path/Hello.S02E01.mp4"}
|
10
12
|
|
11
|
-
subject { EpisodeFile.new(file) }
|
12
|
-
|
13
13
|
it 'extracts the base file name' do
|
14
14
|
expect(subject.basename).to eq 'Hello.S02E01.mp4'
|
15
15
|
end
|
@@ -42,6 +42,21 @@ module Torganiser
|
|
42
42
|
|
43
43
|
end
|
44
44
|
|
45
|
+
context "that is a double episode" do
|
46
|
+
|
47
|
+
let(:file) { "file/path/Hello.2008.S02E01E02.mp4"}
|
48
|
+
|
49
|
+
it 'extracts season number' do
|
50
|
+
expect(subject.season).to eq 2
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'extracts first episode number' do
|
54
|
+
expect(subject.episode).to eq 1
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
end
|
59
|
+
|
45
60
|
context "that has a series name in dot-format" do
|
46
61
|
|
47
62
|
let(:file) { "file/path/Goodbye.Hello.Hamburger.2008.S02E01.mp4"}
|
@@ -56,6 +71,94 @@ module Torganiser
|
|
56
71
|
|
57
72
|
end
|
58
73
|
|
74
|
+
context "in short format" do
|
75
|
+
let(:file) { "file/path/Hello.2014.302.hdtv-lol.mp4" }
|
76
|
+
|
77
|
+
it 'extracts season number' do
|
78
|
+
expect(subject.season).to eq 3
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'extracts episode number' do
|
82
|
+
expect(subject.episode).to eq 2
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with an 'x'" do
|
86
|
+
let(:file) { "file/path/Hello.2014.4x07.hdtv-lol.mp4" }
|
87
|
+
|
88
|
+
it 'extracts season number' do
|
89
|
+
expect(subject.season).to eq 4
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'extracts episode number' do
|
93
|
+
expect(subject.episode).to eq 7
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
context "surrounded in square brackets" do
|
99
|
+
let(:file) { "file/path/Wootle [3x08] Some title here.avi" }
|
100
|
+
|
101
|
+
it 'extracts season number' do
|
102
|
+
expect(subject.season).to eq 3
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'extracts episode number' do
|
106
|
+
expect(subject.episode).to eq 8
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
context "that is dash-separated" do
|
114
|
+
let(:file) { "Wiffle's Berry - S01E12-the title.avi" }
|
115
|
+
|
116
|
+
it 'extracts series correctly' do
|
117
|
+
expect(Series).to receive(:new).with(
|
118
|
+
"Wiffle's Berry", year: nil
|
119
|
+
)
|
120
|
+
subject.series
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'extracts season number' do
|
124
|
+
expect(subject.season).to eq 1
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'extracts episode number' do
|
128
|
+
expect(subject.episode).to eq 12
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "that is a special" do
|
133
|
+
let(:file) { "file/path/Hello.2014.s00.hdtv-lol.mp4" }
|
134
|
+
|
135
|
+
it 'extracts season number as zero' do
|
136
|
+
expect(subject.season).to eq 0
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'extracts episode number as zero' do
|
140
|
+
expect(subject.episode).to eq 0
|
141
|
+
end
|
142
|
+
|
143
|
+
context "with a season specified" do
|
144
|
+
let(:file) { "file/path/Hello.2014.s01.special.hdtv-lol.mp4" }
|
145
|
+
|
146
|
+
it 'extracts season number' do
|
147
|
+
expect(subject.season).to eq 1
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
context "when initialised with a file whose name cannot be parsed" do
|
156
|
+
|
157
|
+
let(:file) { "file/path/Hello.this-contains-no-information.mp4"}
|
158
|
+
|
159
|
+
it 'blows up in a more helpful manner' do
|
160
|
+
expect{ subject.series }.to raise_error(/Unable to parse #{file}/) end
|
161
|
+
|
59
162
|
end
|
60
163
|
|
61
164
|
end
|
data/torganiser.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = [""]
|
11
11
|
spec.summary = %q{Organises episode files according to filename.}
|
12
12
|
spec.description = %q{Organises episode files according to filename.}
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "https://github.com/sergei-matheson/torganiser"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: torganiser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
@@ -170,7 +170,7 @@ files:
|
|
170
170
|
- spec/torganiser/series_spec.rb
|
171
171
|
- spec/torganiser_spec.rb
|
172
172
|
- torganiser.gemspec
|
173
|
-
homepage:
|
173
|
+
homepage: https://github.com/sergei-matheson/torganiser
|
174
174
|
licenses:
|
175
175
|
- MIT
|
176
176
|
metadata: {}
|