blitzcrank 0.1.1 → 0.1.2
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/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
|