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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 350a58c7d89211f5d455326acb3dba3eafb3793a
4
- data.tar.gz: 0c5fc030042cc4dd48cd109fd4e6d1e6d2e1dd3f
3
+ metadata.gz: fa62b57bdb8c2d67d0068a7c999f21bbd0d5cd13
4
+ data.tar.gz: 876710a0c443c89d88ecc420133d1687c44b2ab1
5
5
  SHA512:
6
- metadata.gz: 7f96dc70c919e05ff2bba01ad66e7ea35c74dd81fcfe23643c2d1623da9d403a9bc358a6cb2334fe3a7a98874b259d7142b6c2f068420ea33a59f16249acb3a4
7
- data.tar.gz: b0017d3903fcaa9bb07cd81189d29ec16ce16648b8a8091b89a5af4b27688a2e2b954667c3021284137e9ff4d19caf6b64bc9662a0e2004b8401c794bbecf3fc
6
+ metadata.gz: 6488c31821632f93787d9e1e2a25e3aa0bc0e2f8b0531b55677991a29577a2e215e8acdf2accb1561ffc1e9ee1e2ad76372ef2725ad6d98c8aa072d21ff3d4a7
7
+ data.tar.gz: 4d89ba9e9a1a12944a8f21c775880273e5315028bd6702cd36d34d930802fdee939961af758d399aa900be0b43a087da1da4a0bcc4f7734ef195b53a1cf9f911
data/README.md CHANGED
@@ -24,7 +24,7 @@ Or install it yourself as:
24
24
 
25
25
  ## Usage
26
26
 
27
- TODO: Write usage instructions here
27
+ `torganiser --help`
28
28
 
29
29
  ## Contributing
30
30
 
@@ -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
- parts = episode_info[:series].split('.')
36
- year = YEAR_MATCHER.match(parts.last) ? parts.pop.to_i : nil
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 ||= EPISODE_INFO_MATCHER.match(basename)
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
@@ -27,7 +27,6 @@ module Torganiser
27
27
  end
28
28
 
29
29
  def ignored? file
30
- file = file.strip
31
30
  @ignored_patterns.any? { |pattern| pattern.match file }
32
31
  end
33
32
 
@@ -1,3 +1,3 @@
1
1
  module Torganiser
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -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
@@ -92,7 +92,7 @@ module Torganiser
92
92
 
93
93
  let(:query_results) do
94
94
  [
95
- "/tmp/dir2/file5.alsoignorethis\r\n",
95
+ "/tmp/dir2/file5.alsoignorethis",
96
96
  "/tmp/dir1", "/tmp/dir2/file5.ignoreme",
97
97
  "/tmp/dir1/file3", "/tmp/dir2",
98
98
  "/tmp/dir2/file4"
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.3
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: {}