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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b8fd04be5f9f957818a9d67d0b092123f8273600
4
- data.tar.gz: eaef4cae484010e2a3f17b0cdee60d24a35d0a83
3
+ metadata.gz: b2f16e683446c8c544077387a401edb95935566e
4
+ data.tar.gz: 148abfdb0c175dbebed9f3146c3c4a4276b84ea6
5
5
  SHA512:
6
- metadata.gz: 1962d42effbc0298c48235dc381e1c87a33446eeaab2021172244af3ee50c9dd34fa4a2550ea7ca8e88cd2bfb21dda410d75bc2f6dca3b5c03a2d409b3eec420
7
- data.tar.gz: ef2a7a00ce83ab74b4ea20686ea42f49f3cb393a8a0f6ea02ddd77d7cc1d201a2c00df8155fdfa78c9afa29968550efb32c5ff7e52244515d35a80abe5bf5da4
6
+ metadata.gz: abfc5436dd36673a84a00144a8f01dbd1786aae42852f9dd4339a1fe74c18cd429d15586829eb92bd03995c7f133b9814094d0dba1b5eac30d74b241ce679213
7
+ data.tar.gz: 98f99d4c9da1619b1b926db2fc3486ab35f8427330c3090965ce443231918d0a9cc71f4c0760fd3e2d6516665439fb6da59808c40c446ca22df26d089ad80c54
data/Gemfile CHANGED
@@ -2,3 +2,9 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in blitzcrank.gemspec
4
4
  gemspec
5
+
6
+ group :development, :test do
7
+ gem 'guard-rspec', '~> 4.2.7' #, require: false
8
+ gem 'rspec', '~> 3.0.0.beta2'
9
+ gem 'rspec-nc', '0.2.0'
10
+ end
@@ -0,0 +1,5 @@
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/blitzcrank/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ end
5
+
@@ -23,5 +23,6 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_dependency("colorize", "0.6.0")
25
25
  spec.add_dependency("imdb", "0.8.0")
26
+ spec.add_dependency("ruby-configurable", "1.0.2")
26
27
 
27
28
  end
@@ -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
- @config = {
10
- :base_tv_dir => "",
11
- :base_movie_dir => "",
12
- :season_identifier => "Season ",
13
- :remote_host => "localhost" ,
14
- :remote_user => %x[whoami],
15
- :remote_base_dir => "~/",
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 = YAML::load(IO.read(yaml_path))
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, @config.to_yaml)
32
+ IO.write(yaml_path, Blitzcrank.config.to_yaml)
46
33
  end
47
34
 
48
- def self.transfer_file(remote_path, local_dir)
49
- if @config[:dry_run]
50
- puts "Copying #{remote_path} to #{local_dir}"
51
- else
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
- %x[ssh -q #{@config[:remote_user]}@#{@config[:remote_host]} "cd #{@config[:remote_base_dir]} && find . -type f \\( -iname \'*.avi\' -or -iname \'*.mkv\' -or -iname \'*.mp4\' -or -iname \'*.m4v\' -or -iname \'*.divx\' \\)"]
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(@config[:base_tv_dir])
89
+ Dir.chdir(Blitzcrank.config.base_tv_dir)
104
90
 
105
91
  filesToTransfer.each do |dh|
106
- Dir.chdir(@config[:base_tv_dir])
107
- full_path = dh[:path]
108
- file_name = dh[:name]
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
- end
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 Copy
3
+ def self.sync(video)
4
+ system("cp #{video.remote_path} #{video.local_path}")
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ module Blitzcrank
2
+ class Movie < Video
3
+
4
+ def local_path
5
+ Blitzcrank.config.base_movie_dir + nice_name
6
+ end
7
+
8
+ def is_movie?
9
+ true
10
+ end
11
+
12
+ def is_tv_show?
13
+ false
14
+ end
15
+
16
+ end
17
+ end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Blitzcrank
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -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.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-09-21 00:00:00.000000000 Z
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