movie_organizer 0.1.11 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG +10 -0
- data/Gemfile +2 -1
- data/README.md +27 -14
- data/lib/movie_organizer.rb +33 -14
- data/lib/movie_organizer/file_copier.rb +33 -19
- data/lib/movie_organizer/logger.rb +2 -0
- data/lib/movie_organizer/media_list.rb +1 -15
- data/lib/movie_organizer/medium.rb +176 -0
- data/lib/movie_organizer/movie.rb +50 -18
- data/lib/movie_organizer/options.rb +23 -0
- data/lib/movie_organizer/organizer.rb +29 -11
- data/lib/movie_organizer/settings.rb +3 -0
- data/lib/movie_organizer/string.rb +8 -0
- data/lib/movie_organizer/tmdb_instance.rb +58 -0
- data/lib/movie_organizer/tv_show.rb +51 -37
- data/lib/movie_organizer/tvdb_instance.rb +31 -0
- data/lib/movie_organizer/version.rb +1 -1
- data/lib/movie_organizer/video.rb +39 -11
- data/movie_organizer.gemspec +5 -2
- data/spec/files/Dunkirk.2017.BluRay.1080p.mp4 +0 -0
- data/spec/files/bad.flv +0 -0
- data/spec/files/bad.mp4 +1 -0
- data/spec/files/good.3gp +0 -0
- data/spec/files/good.mov +0 -0
- data/spec/files/good.mp4 +0 -0
- data/spec/files/good.ogv +0 -0
- data/spec/files/good.webm +0 -0
- data/spec/files/{The.Walking.Dead.S04E08.HDTV.x264-2HD.mp4 → tv_shows/The.Walking.Dead.S04E08.HDTV.x264-2HD.mp4} +0 -0
- data/spec/fixtures/.blank_settings.yml +3 -0
- data/spec/lib/movie_organizer/file_copier_spec.rb +5 -2
- data/spec/lib/movie_organizer/media_list_spec.rb +8 -37
- data/spec/lib/movie_organizer/medium_spec.rb +97 -0
- data/spec/lib/movie_organizer/movie_spec.rb +21 -14
- data/spec/lib/movie_organizer/tmdb_instance_spec.rb +39 -0
- data/spec/lib/movie_organizer/tvdb_instance_spec.rb +17 -0
- data/spec/lib/movie_organizer/video_spec.rb +6 -4
- data/spec/lib/movie_organizer_spec.rb +1 -9
- data/spec/spec_helper.rb +5 -0
- data/spec/support/shared_contexts/media_shared.rb +9 -0
- data/spec/support/vcr.rb +17 -0
- metadata +74 -21
- data/lib/movie_organizer/media.rb +0 -110
- data/spec/lib/movie_organizer/media_spec.rb +0 -65
data/spec/support/vcr.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vcr'
|
4
|
+
|
5
|
+
# WebMock.allow_net_connect!
|
6
|
+
|
7
|
+
VCR.configure do |c|
|
8
|
+
c.cassette_library_dir = MovieOrganizer.root.join('spec', 'fixtures', 'vcr_cassettes')
|
9
|
+
c.hook_into :webmock
|
10
|
+
c.default_cassette_options = { record: :new_episodes }
|
11
|
+
# c.default_cassette_options = { record: :once }
|
12
|
+
c.configure_rspec_metadata!
|
13
|
+
c.allow_http_connections_when_no_cassette = true
|
14
|
+
c.ignore_localhost = true
|
15
|
+
c.debug_logger = File.open(File.join('tmp', 'vcr.log'), 'w+')
|
16
|
+
# config.debug_logger = $stderr
|
17
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: movie_organizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Blackburn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -137,21 +137,49 @@ dependencies:
|
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: titleize
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
146
|
-
type: :
|
145
|
+
version: '1.3'
|
146
|
+
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
152
|
+
version: '1.3'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: vcr
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '4.0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '4.0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: webmock
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '3.3'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '3.3'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: colored
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
156
184
|
requirements:
|
157
185
|
- - ">="
|
@@ -165,7 +193,7 @@ dependencies:
|
|
165
193
|
- !ruby/object:Gem::Version
|
166
194
|
version: '0'
|
167
195
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
196
|
+
name: fileutils
|
169
197
|
requirement: !ruby/object:Gem::Requirement
|
170
198
|
requirements:
|
171
199
|
- - ">="
|
@@ -193,33 +221,33 @@ dependencies:
|
|
193
221
|
- !ruby/object:Gem::Version
|
194
222
|
version: '1.2'
|
195
223
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
224
|
+
name: ruby-filemagic
|
197
225
|
requirement: !ruby/object:Gem::Requirement
|
198
226
|
requirements:
|
199
227
|
- - "~>"
|
200
228
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
229
|
+
version: 0.7.2
|
202
230
|
type: :runtime
|
203
231
|
prerelease: false
|
204
232
|
version_requirements: !ruby/object:Gem::Requirement
|
205
233
|
requirements:
|
206
234
|
- - "~>"
|
207
235
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
236
|
+
version: 0.7.2
|
209
237
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
238
|
+
name: themoviedb
|
211
239
|
requirement: !ruby/object:Gem::Requirement
|
212
240
|
requirements:
|
213
241
|
- - "~>"
|
214
242
|
- !ruby/object:Gem::Version
|
215
|
-
version: '1.
|
243
|
+
version: '1.0'
|
216
244
|
type: :runtime
|
217
245
|
prerelease: false
|
218
246
|
version_requirements: !ruby/object:Gem::Requirement
|
219
247
|
requirements:
|
220
248
|
- - "~>"
|
221
249
|
- !ruby/object:Gem::Version
|
222
|
-
version: '1.
|
250
|
+
version: '1.0'
|
223
251
|
- !ruby/object:Gem::Dependency
|
224
252
|
name: trollop
|
225
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -255,36 +283,50 @@ files:
|
|
255
283
|
- lib/movie_organizer.rb
|
256
284
|
- lib/movie_organizer/file_copier.rb
|
257
285
|
- lib/movie_organizer/logger.rb
|
258
|
-
- lib/movie_organizer/media.rb
|
259
286
|
- lib/movie_organizer/media_list.rb
|
287
|
+
- lib/movie_organizer/medium.rb
|
260
288
|
- lib/movie_organizer/movie.rb
|
289
|
+
- lib/movie_organizer/options.rb
|
261
290
|
- lib/movie_organizer/organizer.rb
|
262
291
|
- lib/movie_organizer/settings.rb
|
263
292
|
- lib/movie_organizer/string.rb
|
293
|
+
- lib/movie_organizer/tmdb_instance.rb
|
264
294
|
- lib/movie_organizer/tv_show.rb
|
295
|
+
- lib/movie_organizer/tvdb_instance.rb
|
265
296
|
- lib/movie_organizer/version.rb
|
266
297
|
- lib/movie_organizer/video.rb
|
267
298
|
- movie_organizer.gemspec
|
268
|
-
- spec/files/
|
299
|
+
- spec/files/Dunkirk.2017.BluRay.1080p.mp4
|
300
|
+
- spec/files/bad.flv
|
301
|
+
- spec/files/bad.mp4
|
302
|
+
- spec/files/good.3gp
|
303
|
+
- spec/files/good.mov
|
304
|
+
- spec/files/good.mp4
|
305
|
+
- spec/files/good.ogv
|
306
|
+
- spec/files/good.webm
|
269
307
|
- spec/files/movies/Dunkirk.2017.BluRay.1080p/Dunkirk.2017.BluRay.1080p.mp4
|
270
308
|
- spec/files/movies/The Matrix (1999) [BluRay] [1080p]/The Matrix (1999) [BluRay]
|
271
309
|
[1080p].mp4
|
272
310
|
- spec/files/short_video.mp4
|
311
|
+
- spec/files/tv_shows/The.Walking.Dead.S04E08.HDTV.x264-2HD.mp4
|
273
312
|
- spec/fixtures/.blank_settings.yml
|
274
313
|
- spec/fixtures/.movie_organizer.yml
|
275
314
|
- spec/fixtures/.no_source_directories.yml
|
276
315
|
- spec/lib/movie_organizer/file_copier_spec.rb
|
277
316
|
- spec/lib/movie_organizer/logger_spec.rb
|
278
317
|
- spec/lib/movie_organizer/media_list_spec.rb
|
279
|
-
- spec/lib/movie_organizer/
|
318
|
+
- spec/lib/movie_organizer/medium_spec.rb
|
280
319
|
- spec/lib/movie_organizer/movie_spec.rb
|
281
320
|
- spec/lib/movie_organizer/organizer_spec.rb
|
321
|
+
- spec/lib/movie_organizer/tmdb_instance_spec.rb
|
282
322
|
- spec/lib/movie_organizer/tv_show_spec.rb
|
323
|
+
- spec/lib/movie_organizer/tvdb_instance_spec.rb
|
283
324
|
- spec/lib/movie_organizer/video_spec.rb
|
284
325
|
- spec/lib/movie_organizer_spec.rb
|
285
326
|
- spec/spec_helper.rb
|
286
327
|
- spec/support/filename_mappings.yml
|
287
328
|
- spec/support/shared_contexts/media_shared.rb
|
329
|
+
- spec/support/vcr.rb
|
288
330
|
- tmdb-logo-primary-green.png
|
289
331
|
homepage: https://github.com/midwire/movie_organizer
|
290
332
|
licenses:
|
@@ -311,23 +353,34 @@ signing_key:
|
|
311
353
|
specification_version: 4
|
312
354
|
summary: Automatically organize movies, tv shows and home videos.
|
313
355
|
test_files:
|
314
|
-
- spec/files/
|
356
|
+
- spec/files/Dunkirk.2017.BluRay.1080p.mp4
|
357
|
+
- spec/files/bad.flv
|
358
|
+
- spec/files/bad.mp4
|
359
|
+
- spec/files/good.3gp
|
360
|
+
- spec/files/good.mov
|
361
|
+
- spec/files/good.mp4
|
362
|
+
- spec/files/good.ogv
|
363
|
+
- spec/files/good.webm
|
315
364
|
- spec/files/movies/Dunkirk.2017.BluRay.1080p/Dunkirk.2017.BluRay.1080p.mp4
|
316
365
|
- spec/files/movies/The Matrix (1999) [BluRay] [1080p]/The Matrix (1999) [BluRay]
|
317
366
|
[1080p].mp4
|
318
367
|
- spec/files/short_video.mp4
|
368
|
+
- spec/files/tv_shows/The.Walking.Dead.S04E08.HDTV.x264-2HD.mp4
|
319
369
|
- spec/fixtures/.blank_settings.yml
|
320
370
|
- spec/fixtures/.movie_organizer.yml
|
321
371
|
- spec/fixtures/.no_source_directories.yml
|
322
372
|
- spec/lib/movie_organizer/file_copier_spec.rb
|
323
373
|
- spec/lib/movie_organizer/logger_spec.rb
|
324
374
|
- spec/lib/movie_organizer/media_list_spec.rb
|
325
|
-
- spec/lib/movie_organizer/
|
375
|
+
- spec/lib/movie_organizer/medium_spec.rb
|
326
376
|
- spec/lib/movie_organizer/movie_spec.rb
|
327
377
|
- spec/lib/movie_organizer/organizer_spec.rb
|
378
|
+
- spec/lib/movie_organizer/tmdb_instance_spec.rb
|
328
379
|
- spec/lib/movie_organizer/tv_show_spec.rb
|
380
|
+
- spec/lib/movie_organizer/tvdb_instance_spec.rb
|
329
381
|
- spec/lib/movie_organizer/video_spec.rb
|
330
382
|
- spec/lib/movie_organizer_spec.rb
|
331
383
|
- spec/spec_helper.rb
|
332
384
|
- spec/support/filename_mappings.yml
|
333
385
|
- spec/support/shared_contexts/media_shared.rb
|
386
|
+
- spec/support/vcr.rb
|
@@ -1,110 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'titleize'
|
4
|
-
require 'themoviedb'
|
5
|
-
|
6
|
-
module MovieOrganizer
|
7
|
-
# This meta-class factory accepts the media filename, and from that
|
8
|
-
# determines if it is likely to be:
|
9
|
-
#
|
10
|
-
# 1. a TV show
|
11
|
-
# 2. a Movie
|
12
|
-
# 3. a home video or other type
|
13
|
-
class Media
|
14
|
-
attr_accessor :filename, :options, :logger, :settings
|
15
|
-
|
16
|
-
def self.subtype(filename, options)
|
17
|
-
instance = new(filename, options)
|
18
|
-
return TvShow.new(filename, options) if instance.tv_show?
|
19
|
-
return Movie.new(filename, options) if instance.movie?
|
20
|
-
Video.new(filename, options)
|
21
|
-
end
|
22
|
-
|
23
|
-
def initialize(filename, options)
|
24
|
-
@filename = filename
|
25
|
-
@options = options
|
26
|
-
@tv_show = nil
|
27
|
-
@logger = Logger.instance
|
28
|
-
@settings = Settings.new
|
29
|
-
end
|
30
|
-
|
31
|
-
def tv_show?
|
32
|
-
return @tv_show unless @tv_show.nil?
|
33
|
-
@tv_show = false
|
34
|
-
@tv_show = true unless filename.match(/S\d+E\d+/i).nil?
|
35
|
-
@tv_show = true unless filename.match(/\d+x\d+/i).nil?
|
36
|
-
@tv_show
|
37
|
-
end
|
38
|
-
|
39
|
-
def movie?
|
40
|
-
return @movie unless @movie.nil?
|
41
|
-
@movie = false
|
42
|
-
Tmdb::Api.key(MovieOrganizer.tmdb_key)
|
43
|
-
# Remove the year and sanitize
|
44
|
-
title = sanitize(File.basename(filename, ext)).gsub(/[\s\.\-\_]\(?\d\d\d\d\)?/, '').strip
|
45
|
-
matches = Tmdb::Movie.find(title)
|
46
|
-
@movie = matches.any?
|
47
|
-
@movie
|
48
|
-
end
|
49
|
-
|
50
|
-
def year
|
51
|
-
md = basename.match(/\((\d\d\d\d)\)|(19\d\d)|(20\d\d)/)
|
52
|
-
# try dirname if filename has no year
|
53
|
-
md = dirname.match(/\((\d\d\d\d)\)|(19\d\d)|(20\d\d)/) if md.nil?
|
54
|
-
md ? md.captures.compact.first : nil
|
55
|
-
end
|
56
|
-
|
57
|
-
protected
|
58
|
-
|
59
|
-
def basename
|
60
|
-
File.basename(filename)
|
61
|
-
end
|
62
|
-
|
63
|
-
def ext
|
64
|
-
File.extname(filename)
|
65
|
-
end
|
66
|
-
|
67
|
-
def dirname
|
68
|
-
File.dirname(filename)
|
69
|
-
end
|
70
|
-
|
71
|
-
def verbose?
|
72
|
-
options[:verbose]
|
73
|
-
end
|
74
|
-
|
75
|
-
def dry_run?
|
76
|
-
options[:dry_run]
|
77
|
-
end
|
78
|
-
|
79
|
-
# rubocop:disable Metrics/AbcSize
|
80
|
-
# rubocop:disable Metrics/MethodLength
|
81
|
-
def sanitize(str)
|
82
|
-
cleanstr = str.gsub(/-\s*-/, '')
|
83
|
-
cleanstr = cleanstr.gsub(/\[?1080p\]?/, '').strip
|
84
|
-
cleanstr = cleanstr.gsub(/m?\[?720p\]?/, '').strip
|
85
|
-
cleanstr = cleanstr.gsub(/\[[^\]]+\]/, '').strip
|
86
|
-
cleanstr = cleanstr.gsub(/EXTENDED/, '').strip
|
87
|
-
cleanstr = cleanstr.gsub(/YIFY/, '').strip
|
88
|
-
cleanstr = cleanstr.gsub(/VPPV/, '').strip
|
89
|
-
cleanstr = cleanstr.gsub(/BluRay/i, '').strip
|
90
|
-
cleanstr = cleanstr.gsub(/BrRip/i, '').strip
|
91
|
-
cleanstr = cleanstr.gsub(/[\s\.]Br[\s\.]?/i, '').strip
|
92
|
-
cleanstr = cleanstr.gsub(/BdRip/i, '').strip
|
93
|
-
cleanstr = cleanstr.gsub(/ECI/i, '').strip
|
94
|
-
cleanstr = cleanstr.gsub(/HDTV/i, '').strip
|
95
|
-
cleanstr = cleanstr.gsub(/WEBRip/i, '').strip
|
96
|
-
cleanstr = cleanstr.gsub(/x264/, '').strip
|
97
|
-
cleanstr = cleanstr.gsub(/AAC/, '').strip
|
98
|
-
cleanstr = cleanstr.gsub(/-lol/i, '').strip
|
99
|
-
cleanstr = cleanstr.gsub(/\+HI/i, '').strip
|
100
|
-
cleanstr = cleanstr.gsub(/muxed/i, '').strip
|
101
|
-
cleanstr = cleanstr.gsub(/\d\d\d+mb/i, '').strip
|
102
|
-
# cleanstr = cleanstr.gsub(/[\.\s-]us[\.\s-]/i, ' ').strip
|
103
|
-
cleanstr = cleanstr.gsub(/-\s*/, '').strip
|
104
|
-
cleanstr = cleanstr.gsub(/\s\s+/, ' ').strip
|
105
|
-
cleanstr.gsub(/[\.\+]/, ' ').strip
|
106
|
-
end
|
107
|
-
# rubocop:enable Metrics/MethodLength
|
108
|
-
# rubocop:enable Metrics/AbcSize
|
109
|
-
end
|
110
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# rubocop:disable Metrics/BlockLength
|
4
|
-
module MovieOrganizer
|
5
|
-
RSpec.describe Media, type: :lib do
|
6
|
-
include_context 'media_shared'
|
7
|
-
|
8
|
-
context '.subtype' do
|
9
|
-
tv_shows = {
|
10
|
-
'SnnEnn' => 'The.Walking.Dead.S04E08.HDTV.x264-2HD',
|
11
|
-
'nxn' => 'The.Walking.Dead.4x0.HDTV.x264-2HD',
|
12
|
-
'nnxn' => 'The.Walking.Dead.12x8.HDTV.x264-2HD',
|
13
|
-
'nnxnn' => 'The.Walking.Dead.12x08.HDTV.x264-2HD',
|
14
|
-
'nxnn' => 'The.Walking.Dead.2x18.HDTV.x264-2HD'
|
15
|
-
}
|
16
|
-
|
17
|
-
tv_shows.each_pair do |syntax, filename|
|
18
|
-
it "returns a TvShow with season and episode syntax: #{syntax}" do
|
19
|
-
filename = create_test_file(
|
20
|
-
filename: filename,
|
21
|
-
extension: 'mp4'
|
22
|
-
).first
|
23
|
-
expect(Media.subtype(filename, default_options)).to be_a(TvShow)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
movies = [
|
28
|
-
'Coco.2017.1080p.BluRay.x264-[BOGUS.IT]',
|
29
|
-
'Beetlejuice',
|
30
|
-
'Justice.League.2017.1080p.BluRay.x264-[YTS.AM]',
|
31
|
-
'Jumanji.Welcome.To.The.Jungle.2017.1080p.WEBRip.x264-[YTS.AM].mp4'
|
32
|
-
]
|
33
|
-
|
34
|
-
movies.each do |filename|
|
35
|
-
it "returns a Movie for '#{filename}'" do
|
36
|
-
expect(Tmdb::Movie).to receive(:find).at_least(1).times.and_return([1])
|
37
|
-
filename = create_test_file(
|
38
|
-
filename: filename
|
39
|
-
).first
|
40
|
-
expect(Media.subtype(filename, default_options)).to be_a(Movie)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
videos = [
|
45
|
-
'IMG_2052',
|
46
|
-
'IMG_3322',
|
47
|
-
'VID_3322',
|
48
|
-
'VIDEO_3322',
|
49
|
-
'Our Summer Vacation',
|
50
|
-
'Tom and Jerry on the Beach'
|
51
|
-
]
|
52
|
-
|
53
|
-
videos.each do |filename|
|
54
|
-
it "returns a Video for '#{filename}'" do
|
55
|
-
expect(Tmdb::Movie).to receive(:find).at_least(1).times.and_return([])
|
56
|
-
filename = create_test_file(
|
57
|
-
filename: filename
|
58
|
-
).first
|
59
|
-
expect(Media.subtype(filename, default_options)).to be_a(Video)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
# rubocop:enable Metrics/BlockLength
|