torganiser 0.0.3 → 0.0.5
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.
- 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: {}
|