blitzcrank 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +6 -0
- data/Guardfile +5 -0
- data/blitzcrank.gemspec +1 -0
- data/lib/blitzcrank.rb +24 -78
- data/lib/blitzcrank/copy.rb +7 -0
- data/lib/blitzcrank/movie.rb +17 -0
- data/lib/blitzcrank/rsync.rb +7 -0
- data/lib/blitzcrank/tv_show.rb +26 -0
- data/lib/blitzcrank/version.rb +1 -1
- data/lib/blitzcrank/video.rb +80 -0
- data/spec/lib/copy_spec.rb +15 -0
- data/spec/lib/movie_spec.rb +27 -0
- data/spec/lib/tv_show_spec.rb +46 -0
- data/spec/lib/video_spec.rb +16 -0
- metadata +31 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2f16e683446c8c544077387a401edb95935566e
|
4
|
+
data.tar.gz: 148abfdb0c175dbebed9f3146c3c4a4276b84ea6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abfc5436dd36673a84a00144a8f01dbd1786aae42852f9dd4339a1fe74c18cd429d15586829eb92bd03995c7f133b9814094d0dba1b5eac30d74b241ce679213
|
7
|
+
data.tar.gz: 98f99d4c9da1619b1b926db2fc3486ab35f8427330c3090965ce443231918d0a9cc71f4c0760fd3e2d6516665439fb6da59808c40c446ca22df26d089ad80c54
|
data/Gemfile
CHANGED
data/Guardfile
ADDED
data/blitzcrank.gemspec
CHANGED
data/lib/blitzcrank.rb
CHANGED
@@ -1,61 +1,47 @@
|
|
1
1
|
require "blitzcrank/version"
|
2
|
+
require File.join(File.dirname(__FILE__), "blitzcrank/video.rb")
|
3
|
+
Dir[File.join(File.dirname(__FILE__), "blitzcrank/*.rb")].each {|f| require f }
|
2
4
|
require "colorize"
|
5
|
+
require "configurable"
|
6
|
+
require "fileutils"
|
3
7
|
require "yaml"
|
4
|
-
require "imdb"
|
5
8
|
|
6
9
|
module Blitzcrank
|
10
|
+
include Configurable
|
7
11
|
|
8
12
|
# Configuration defaults
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
:dry_run => false
|
17
|
-
}
|
18
|
-
|
19
|
-
@valid_config_keys = @config.keys
|
20
|
-
|
21
|
-
@tv_show_regex = /(.*)\.s?(\d{1,2})[ex](\d{2})/i # Supports s01e01, 1x03
|
22
|
-
|
23
|
-
# Configure through hash
|
24
|
-
def self.configure(opts = {})
|
25
|
-
opts.each {|k,v| @config[k.to_sym] = v if @valid_config_keys.include? k.to_sym}
|
26
|
-
end
|
13
|
+
configurable_options :base_tv_dir => "",
|
14
|
+
:base_movie_dir => "",
|
15
|
+
:season_identifier => "Season ",
|
16
|
+
:remote_host => "localhost" ,
|
17
|
+
:remote_user => %x[whoami],
|
18
|
+
:remote_base_dir => "~/",
|
19
|
+
:dry_run => false
|
27
20
|
|
28
21
|
def self.configure_with(yaml_path)
|
29
22
|
begin
|
30
|
-
config
|
23
|
+
Blitzcrank.config.update(YAML.load(IO.read(yaml_path)))
|
31
24
|
rescue Errno::ENOENT
|
32
25
|
log(:warning, "YAML configuration file couldn't be found. Using defaults."); return
|
33
26
|
rescue Psych::SyntaxError
|
34
27
|
log(:warning, "YAML configuration file contains invalid syntax. Using defaults."); return
|
35
28
|
end
|
36
|
-
|
37
|
-
configure(config)
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.config
|
41
|
-
@config
|
42
29
|
end
|
43
30
|
|
44
31
|
def self.write_sample_config(yaml_path)
|
45
|
-
IO.write(yaml_path,
|
32
|
+
IO.write(yaml_path, Blitzcrank.config.to_yaml)
|
46
33
|
end
|
47
34
|
|
48
|
-
def self.transfer_file(
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
system("rsync -avz #{ '--bwlimit=' + @config[:bwlimit] unless @config[:bwlimit].nil? } --progress --rsh='ssh' \"#{@config[:remote_user]}@#{@config[:remote_host]}:#{@config[:remote_base_dir]}#{remote_path.gsub(' ', '\\ ')}\" \"#{local_dir}\"")
|
35
|
+
def self.transfer_file(video)
|
36
|
+
puts "Copying #{video.remote_path} to #{video.local_path}"
|
37
|
+
if !Blitzcrank.config.dry_run
|
38
|
+
Rsync.sync(video)
|
53
39
|
end
|
54
40
|
end
|
55
41
|
|
56
42
|
# get a listing of all remote files that would be considered "videos"
|
57
43
|
def self.remote_video_file_list
|
58
|
-
|
44
|
+
%x[ssh -q #{Blitzcrank.config.remote_user}@#{Blitzcrank.config.remote_host} "cd #{Blitzcrank.config.remote_base_dir} && find . -type f \\( -iname \'*.avi\' -or -iname \'*.mkv\' -or -iname \'*.mp4\' -or -iname \'*.m4v\' -or -iname \'*.divx\' \\)"]
|
59
45
|
end
|
60
46
|
|
61
47
|
def self.file_menu(search_array = nil)
|
@@ -100,54 +86,14 @@ module Blitzcrank
|
|
100
86
|
|
101
87
|
# any files (hashes) passed into here will be checked against our local TV folders and IMDB to see if it's a movie
|
102
88
|
def self.transfer_files(filesToTransfer)
|
103
|
-
Dir.chdir(
|
89
|
+
Dir.chdir(Blitzcrank.config.base_tv_dir)
|
104
90
|
|
105
91
|
filesToTransfer.each do |dh|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
nice_name = Blitzcrank.nice_tv_name(file_name)
|
110
|
-
directories = Dir.glob(nice_name, File::FNM_CASEFOLD)
|
111
|
-
if directories.count > 0 # see if we already have a directory for this tv show
|
112
|
-
nice_name = directories.first
|
113
|
-
season_dir = "#{Dir.pwd}/#{nice_name}/#{@config[:season_identifier]}#{Blitzcrank.season(file_name)}"
|
114
|
-
Dir.mkdir(season_dir) unless Dir.exists?(season_dir) # make the folder if it doesn't exist
|
115
|
-
Blitzcrank.transfer_file(full_path, season_dir)
|
116
|
-
elsif Blitzcrank.is_movie?(file_name)
|
117
|
-
Blitzcrank.transfer_file(full_path, @config[:base_movie_dir])
|
92
|
+
video = Video.with_path dh[:path]
|
93
|
+
if video.is_tv_show?
|
94
|
+
FileUtils.mkdir_p video.season_path
|
118
95
|
end
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
# pulls the season number froma file
|
123
|
-
def self.season(file_name)
|
124
|
-
@tv_show_regex.match(file_name)
|
125
|
-
$2.gsub(/\A0+/, '')
|
126
|
-
end
|
127
|
-
|
128
|
-
def self.nice_tv_name(file_name)
|
129
|
-
unless @tv_show_regex.match(file_name).nil?
|
130
|
-
showName = $1
|
131
|
-
wordsInShowName = showName.gsub(/[\._]/, ' ').downcase.split(" ") # strip . and _
|
132
|
-
wordsInShowName.each do |word|
|
133
|
-
if wordsInShowName.index(word) == 0 || /^(in|a|the|and|on)$/i.match(word).nil?
|
134
|
-
word.capitalize!
|
135
|
-
end
|
136
|
-
end
|
137
|
-
wordsInShowName.join(" ").gsub(/\b(us|uk|\d{4})$/i, '(\1)') # adding parens around US/UK marked shows, or shows with years
|
138
|
-
else
|
139
|
-
file_name
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def self.is_movie?(file_name)
|
144
|
-
unless /^(.*).(\d{4}|dvdrip)/i.match(file_name).nil?
|
145
|
-
movie_name = $1
|
146
|
-
nice_movie_name = movie_name.gsub('.', ' ').downcase
|
147
|
-
i = Imdb::Search.new(nice_movie_name)
|
148
|
-
i.movies.size > 0
|
149
|
-
else
|
150
|
-
false
|
96
|
+
Blitzcrank.transfer_file(video)
|
151
97
|
end
|
152
98
|
end
|
153
99
|
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module Blitzcrank
|
2
|
+
class Rsync < Copy
|
3
|
+
def self.sync(video)
|
4
|
+
system("rsync -avz #{ '--bwlimit=' + Blitzcrank.config.bwlimit if Blitzcrank.config.respond_to?(:bwlimit) } --progress --rsh='ssh' \"#{Blitzcrank.config.remote_user}@#{Blitzcrank.config.remote_host}:#{Blitzcrank.config.remote_base_dir}#{video.remote_path.gsub(' ', '\\ ')}\" \"#{video.local_path}\"")
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Blitzcrank
|
2
|
+
class TVShow < Video
|
3
|
+
|
4
|
+
def season_path
|
5
|
+
Blitzcrank.config.base_tv_dir + nice_name + "/" + Blitzcrank.config.season_identifier + season
|
6
|
+
end
|
7
|
+
|
8
|
+
def local_path
|
9
|
+
season_path + "/" + @file_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def season
|
13
|
+
TV_SHOW_REGEX.match(@file_name)
|
14
|
+
$2.gsub(/\A0+/, '')
|
15
|
+
end
|
16
|
+
|
17
|
+
def is_movie?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_tv_show?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/blitzcrank/version.rb
CHANGED
@@ -0,0 +1,80 @@
|
|
1
|
+
require "imdb"
|
2
|
+
module Blitzcrank
|
3
|
+
class Video
|
4
|
+
|
5
|
+
TV_SHOW_REGEX = /(.*)[\. ]s?(\d{1,2})[ex](\d{2})/i # Supports s01e01, 1x03
|
6
|
+
MOVIE_REGEX = /^(.*).(\d{4}|dvdrip)/i
|
7
|
+
|
8
|
+
def self.with_path(file_path)
|
9
|
+
file_name = Video.file_name(file_path)
|
10
|
+
if Video.is_tv_show? file_name
|
11
|
+
return TVShow.new file_path
|
12
|
+
elsif Video.is_movie? file_name
|
13
|
+
return Movie.new file_path
|
14
|
+
end
|
15
|
+
return Video.new file_path
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.file_name(file_path)
|
19
|
+
file_path.split('/').last
|
20
|
+
end
|
21
|
+
|
22
|
+
# returns if this is a TV show or not
|
23
|
+
def self.is_tv_show?(file_name)
|
24
|
+
TV_SHOW_REGEX.match(file_name).nil? == false
|
25
|
+
end
|
26
|
+
|
27
|
+
# movie methods
|
28
|
+
def self.is_movie?(file_name)
|
29
|
+
if Video.is_tv_show?(file_name)
|
30
|
+
return false
|
31
|
+
elsif MOVIE_REGEX.match(file_name).nil? == false
|
32
|
+
movie_name = $1
|
33
|
+
nice_movie_name = movie_name.gsub('.', ' ').downcase
|
34
|
+
i = Imdb::Search.new(nice_movie_name)
|
35
|
+
i.movies.size > 0
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(file_path)
|
42
|
+
@file_path = file_path
|
43
|
+
@file_name = Video.file_name file_path
|
44
|
+
end
|
45
|
+
|
46
|
+
def remote_path
|
47
|
+
@file_path
|
48
|
+
end
|
49
|
+
|
50
|
+
def file_name
|
51
|
+
@file_name
|
52
|
+
end
|
53
|
+
|
54
|
+
def nice_name
|
55
|
+
unless TV_SHOW_REGEX.match(@file_name).nil?
|
56
|
+
showName = $1
|
57
|
+
wordsInShowName = showName.gsub(/[\._]/, ' ').downcase.split(" ") # strip . and _
|
58
|
+
wordsInShowName.each do |word|
|
59
|
+
if wordsInShowName.index(word) == 0 || /^(in|a|the|and|on)$/i.match(word).nil?
|
60
|
+
word.capitalize!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
wordsInShowName.join(" ").gsub(/\b(us|uk|\d{4})$/i, '(\1)') # adding parens around US/UK marked shows, or shows with years
|
64
|
+
else
|
65
|
+
@file_name
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# returns if this is a TV show or not
|
70
|
+
def is_tv_show?
|
71
|
+
Video.is_tv_show?(@file_name)
|
72
|
+
end
|
73
|
+
|
74
|
+
# movie methods
|
75
|
+
def is_movie?
|
76
|
+
Video.is_movie?(@file_name)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require './lib/blitzcrank.rb'
|
2
|
+
|
3
|
+
module Blitzcrank
|
4
|
+
describe Copy do
|
5
|
+
|
6
|
+
let(:video) { Video.with_path 'The.League.S03E03.720p.HDTV.x264-IMMERSE.mkv' }
|
7
|
+
|
8
|
+
it "copies video files" do
|
9
|
+
allow(Copy).to receive(:system).and_return(0)
|
10
|
+
Copy.sync(video)
|
11
|
+
expect(Copy).to have_received(:system)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require './lib/blitzcrank.rb'
|
2
|
+
|
3
|
+
module Blitzcrank
|
4
|
+
describe Movie do
|
5
|
+
let(:movie_file_names) {['Minority.Report.2002.720p.BluRay.DTS.x264-HiDt.mkv',
|
6
|
+
'Army.Of.Darkness.1992.Bluray.1080p.DTSMA.x264.mkv']}
|
7
|
+
let(:movies) { movie_file_names.map {|f| Movie.new f } }
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
Blitzcrank.config.update(base_movie_dir: 'Movies/')
|
11
|
+
end
|
12
|
+
|
13
|
+
it "correctly detects movies" do
|
14
|
+
movies.each do |video|
|
15
|
+
expect(video.is_movie?).to eq(true)
|
16
|
+
expect(video.is_tv_show?).to eq(false)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "correctly gets the local path for a movie" do
|
21
|
+
movies.each_with_index do |video, i|
|
22
|
+
expect(video.local_path).to eql("Movies/#{movie_file_names[i]}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require './lib/blitzcrank.rb'
|
2
|
+
|
3
|
+
module Blitzcrank
|
4
|
+
describe TVShow do
|
5
|
+
let(:tv_file_names) {['The.League.S03E03.720p.HDTV.x264-IMMERSE.mkv',
|
6
|
+
'doctor_who_2005.8x05.time_heist.720p_hdtv_x264-fov.mkv',
|
7
|
+
'Doctor Who S04E14 The Next Doctor 720p BluRay DTS5.1 x264-BG.mkv']}
|
8
|
+
let(:tv_show_names) {['The League',
|
9
|
+
'Doctor Who (2005)',
|
10
|
+
'Doctor Who']}
|
11
|
+
let(:tv_show_seasons) {['3',
|
12
|
+
'8',
|
13
|
+
'4']}
|
14
|
+
let(:tv_shows) { tv_file_names.map {|f| TVShow.new f } }
|
15
|
+
|
16
|
+
before(:all) do
|
17
|
+
Blitzcrank.config.update(base_tv_dir: 'TV/')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "correctly detects TV shows" do
|
21
|
+
tv_shows.each do |video|
|
22
|
+
expect(video.is_tv_show?).to eq(true)
|
23
|
+
expect(video.is_movie?).to eq(false)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "correctly parses file names into TV show names" do
|
28
|
+
tv_shows.each_with_index do |video, i|
|
29
|
+
expect(video.nice_name).to eql(tv_show_names[i])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "correctly parses seasons from TV show file names" do
|
34
|
+
tv_shows.each_with_index do |video, i|
|
35
|
+
expect(video.season).to eql(tv_show_seasons[i])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "correctly gets the local path for a TV show" do
|
40
|
+
tv_shows.each_with_index do |video, i|
|
41
|
+
expect(video.local_path).to eql("TV/Season #{tv_show_seasons[i]}/#{tv_show_names[i]}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require './lib/blitzcrank.rb'
|
2
|
+
|
3
|
+
module Blitzcrank
|
4
|
+
describe Video do
|
5
|
+
let(:movie_file_names) {['Minority.Report.2002.720p.BluRay.DTS.x264-HiDt.mkv',
|
6
|
+
'Army.Of.Darkness.1992.Bluray.1080p.DTSMA.x264.mkv']}
|
7
|
+
let(:movies) { movie_file_names.map {|f| Video.with_path f } }
|
8
|
+
|
9
|
+
it "correctly creates movies" do
|
10
|
+
movies.each do |video|
|
11
|
+
expect(video.class).to eq(Movie)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blitzcrank
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pyro2927
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.8.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: ruby-configurable
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.0.2
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.0.2
|
69
83
|
description: Copy down remote files and sort into nice folders
|
70
84
|
email:
|
71
85
|
- joseph@pintozzi.com
|
@@ -78,6 +92,7 @@ extra_rdoc_files: []
|
|
78
92
|
files:
|
79
93
|
- ".gitignore"
|
80
94
|
- Gemfile
|
95
|
+
- Guardfile
|
81
96
|
- LICENSE
|
82
97
|
- LICENSE.txt
|
83
98
|
- README.md
|
@@ -93,7 +108,16 @@ files:
|
|
93
108
|
- img/Rocket_Grab.jpg
|
94
109
|
- img/Static_Field.jpg
|
95
110
|
- lib/blitzcrank.rb
|
111
|
+
- lib/blitzcrank/copy.rb
|
112
|
+
- lib/blitzcrank/movie.rb
|
113
|
+
- lib/blitzcrank/rsync.rb
|
114
|
+
- lib/blitzcrank/tv_show.rb
|
96
115
|
- lib/blitzcrank/version.rb
|
116
|
+
- lib/blitzcrank/video.rb
|
117
|
+
- spec/lib/copy_spec.rb
|
118
|
+
- spec/lib/movie_spec.rb
|
119
|
+
- spec/lib/tv_show_spec.rb
|
120
|
+
- spec/lib/video_spec.rb
|
97
121
|
homepage: ''
|
98
122
|
licenses:
|
99
123
|
- MIT
|
@@ -118,4 +142,8 @@ rubygems_version: 2.2.2
|
|
118
142
|
signing_key:
|
119
143
|
specification_version: 4
|
120
144
|
summary: Uhhh.... torrent management gem?
|
121
|
-
test_files:
|
145
|
+
test_files:
|
146
|
+
- spec/lib/copy_spec.rb
|
147
|
+
- spec/lib/movie_spec.rb
|
148
|
+
- spec/lib/tv_show_spec.rb
|
149
|
+
- spec/lib/video_spec.rb
|