xbmc-sql 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +20 -0
  5. data/CHANGELOG.markdown +5 -0
  6. data/Gemfile +9 -0
  7. data/Guardfile +13 -0
  8. data/LICENSE +20 -0
  9. data/README.markdown +92 -0
  10. data/Rakefile +49 -0
  11. data/app/models/xbmc_sql/base.rb +45 -0
  12. data/app/models/xbmc_sql/file.rb +17 -0
  13. data/app/models/xbmc_sql/movie.rb +78 -0
  14. data/app/models/xbmc_sql/path.rb +33 -0
  15. data/app/models/xbmc_sql/set.rb +9 -0
  16. data/bin/rails +12 -0
  17. data/lib/tasks/xbmc_sql_tasks.rake +13 -0
  18. data/lib/xbmc_sql.rb +34 -0
  19. data/lib/xbmc_sql/engine.rb +13 -0
  20. data/lib/xbmc_sql/nfo_file.rb +76 -0
  21. data/lib/xbmc_sql/rating_updater.rb +36 -0
  22. data/lib/xbmc_sql/top_250_updater.rb +102 -0
  23. data/lib/xbmc_sql/version.rb +3 -0
  24. data/spec/factories/movie.rb +5 -0
  25. data/spec/factories/path.rb +5 -0
  26. data/spec/fixtures/movie.nfo +595 -0
  27. data/spec/fixtures/movie.nfo.bak +595 -0
  28. data/spec/fixtures/movie.tmp.nfo +595 -0
  29. data/spec/lib/xbmc_sql/nfo_file_spec.rb +62 -0
  30. data/spec/lib/xbmc_sql/rating_updater_spec.rb +48 -0
  31. data/spec/lib/xbmc_sql/top_250_updater_spec.rb +49 -0
  32. data/spec/lib/xbmc_sql_spec.rb +29 -0
  33. data/spec/models/xbmc_sql/base_spec.rb +7 -0
  34. data/spec/models/xbmc_sql/file_spec.rb +16 -0
  35. data/spec/models/xbmc_sql/movie_spec.rb +115 -0
  36. data/spec/models/xbmc_sql/path_spec.rb +49 -0
  37. data/spec/models/xbmc_sql/set_spec.rb +5 -0
  38. data/spec/spec_helper.rb +23 -0
  39. data/spec/test_app/Rakefile +6 -0
  40. data/spec/test_app/bin/bundle +3 -0
  41. data/spec/test_app/bin/rails +4 -0
  42. data/spec/test_app/bin/rake +4 -0
  43. data/spec/test_app/config.ru +4 -0
  44. data/spec/test_app/config/application.rb +16 -0
  45. data/spec/test_app/config/boot.rb +5 -0
  46. data/spec/test_app/config/database.yml +20 -0
  47. data/spec/test_app/config/environment.rb +5 -0
  48. data/spec/test_app/config/environments/development.rb +8 -0
  49. data/spec/test_app/config/environments/test.rb +7 -0
  50. data/spec/test_app/db/fresh_db.sqlite3 +0 -0
  51. data/spec/test_app/db/schema.rb +415 -0
  52. data/spec/test_app/log/.keep +0 -0
  53. data/xbmc_sql.gemspec +34 -0
  54. metadata +265 -0
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe XbmcSql::NfoFile do
4
+ let(:nfo_file) { 'spec/fixtures/movie.nfo' }
5
+ let(:tmp_file) { 'spec/fixtures/movie.tmp.nfo' }
6
+
7
+ before do
8
+ FileUtils.rm tmp_file if File.exist? tmp_file
9
+ FileUtils.copy nfo_file, tmp_file
10
+ end
11
+
12
+ subject { XbmcSql::NfoFile.new tmp_file }
13
+
14
+ it "has attribute readers for singular attributes" do
15
+ expect(subject.title).to eq 'The Grand Budapest Hotel'
16
+ expect(subject.id).to eq 'tt2278388'
17
+ expect(subject.originaltitle).to eq 'The Grand Budapest Hotel'
18
+ expect(subject.sorttitle).to eq 'Grand Budapest Hotel'
19
+ expect(subject.year).to eq '2014'
20
+ expect(subject.releasedate).to eq '6/27/2014'
21
+ expect(subject.top250).to eq '138'
22
+ expect(subject.rating).to eq '8.3'
23
+ expect(subject.votes).to eq '103,763'
24
+ expect(subject.mpaa).to eq 'Rated R for language, some sexual content and violence'
25
+ expect(subject.studio).to eq 'Fox Searchlight Pictures'
26
+ expect(subject.runtime).to eq '99'
27
+ expect(subject.playcount).to eq '1'
28
+ expect(subject.certification).to match /USA:R/
29
+ expect(subject.outline).to match /The adventures of Gustave/
30
+ expect(subject.plot).to match /GRAND BUDAPEST HOTEL recounts/
31
+ end
32
+
33
+ it "can write attributes for singular attributes" do
34
+ subject.title = "Foo Movie"
35
+ expect(subject.title).to eq 'Foo Movie'
36
+ end
37
+
38
+ it "has attribute readers for plural attributes" do
39
+ expect(subject.countries).to eq ['USA', 'Germany']
40
+ expect(subject.genres).to eq ['Comedy', 'Drama']
41
+ expect(subject.directors).to eq ['Wes Anderson']
42
+ end
43
+
44
+ it "can write attributes for plural attributes" do
45
+ subject.genres = ["Foo", "Bar"]
46
+ expect(subject.genres).to eq ["Foo", "Bar"]
47
+ end
48
+
49
+ describe "#actors" do
50
+ it "has actors" do
51
+ expect(subject.actors).to be_a Array
52
+ expect(subject.actors.first['name'][0]).to eq 'Ralph Fiennes'
53
+ end
54
+ end
55
+
56
+ describe "save!" do
57
+ it "saves the file" do
58
+ subject.title = 'Foo and a half'
59
+ subject.save!
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe XbmcSql::RatingUpdater do
4
+
5
+ before { described_class.any_instance.stub :puts }
6
+
7
+ describe ".go!" do
8
+ let(:scraper) { double XbmcSql::RatingUpdater, scrape!: true }
9
+
10
+ it "runs the test" do
11
+ expect(XbmcSql::RatingUpdater).to receive(:new).at_least(:once).and_return scraper
12
+ XbmcSql::RatingUpdater.go!
13
+ end
14
+ end
15
+
16
+ describe "#scrape" do
17
+ let(:scraper) { described_class.new movie }
18
+
19
+ context "with an imdb-less movie" do
20
+ let(:movie) { create :movie, rating: '8.2' }
21
+
22
+ it "doesn't do anything" do
23
+ expect(HTTParty).not_to receive :get
24
+ scraper.scrape!
25
+ expect(movie.rating).to eq '8.2'
26
+ end
27
+ end
28
+
29
+ context "with an imdb movie" do
30
+ let(:movie) { create :movie, rating: '8.2', imdb_id: 'tt1234' }
31
+ let(:expected_url) { "http://www.omdbapi.com/?i=tt1234" }
32
+
33
+ before { expect(HTTParty).to receive(:get).with(expected_url).and_return response }
34
+
35
+ context "when successfully scraped" do
36
+ let(:body) { {'imdbRating' => '7', 'imdbVotes' => '1,234'} }
37
+ let(:response) { double HTTParty::Response, body: body.to_json }
38
+
39
+ it "updates it" do
40
+ scraper.scrape!
41
+ movie.reload
42
+ expect(movie.rating).to eq '7'
43
+ expect(movie.rating_votes).to eq '1,234'
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe XbmcSql::Top250Updater do
4
+
5
+ before { described_class.stub :puts }
6
+ before { described_class.any_instance.stub :puts }
7
+
8
+ describe ".go!" do
9
+ let(:updater) { double XbmcSql::Top250Updater, scrape!: true }
10
+
11
+ before { expect(XbmcSql::Top250Updater).to receive(:new).and_return updater }
12
+
13
+ context "when all is well" do
14
+ it "updates all the ratings and returns true" do
15
+ expect(updater).to receive :scrape
16
+ expect(updater).to receive :update_current
17
+ expect(updater).to receive :remove_old
18
+ expect(updater).to receive :note_missing
19
+ expect(XbmcSql::Top250Updater.go!).to be true
20
+ end
21
+ end
22
+
23
+ context "when an error occurs" do
24
+ it "returns false" do
25
+ expect(updater).to receive(:scrape).and_raise StandardError
26
+ expect(updater).not_to receive :update_current
27
+ expect(updater).not_to receive :remove_old
28
+ expect(updater).not_to receive :note_missing
29
+ expect(XbmcSql::Top250Updater.go!).to be false
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "#scrape" do
35
+ pending
36
+ end
37
+
38
+ describe "#update_current" do
39
+ pending
40
+ end
41
+
42
+ describe "#remove_old" do
43
+ pending
44
+ end
45
+
46
+ describe "#note_missing" do
47
+ pending
48
+ end
49
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe XbmcSql do
4
+ describe ".register_path_mapping" do
5
+ it "registers the path mappping" do
6
+ XbmcSql.register_path_mapping 'foo', 'bar'
7
+ expect(XbmcSql.path_mappings['foo']).to eq 'bar'
8
+ XbmcSql.path_mappings = {}
9
+ end
10
+ end
11
+
12
+ describe ".use_path_mappings?" do
13
+ context "when there's path mappings" do
14
+ before { XbmcSql.stub(:path_mappings).and_return foo: :bar }
15
+
16
+ it "is true" do
17
+ expect(XbmcSql.use_path_mappings?).to be true
18
+ end
19
+ end
20
+
21
+ context "when there's no path mappings" do
22
+ before { XbmcSql.stub(:path_mappings).and_return Hash.new }
23
+
24
+ it "is false" do
25
+ expect(XbmcSql.use_path_mappings?).to be false
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module XbmcSql
4
+ describe Base do
5
+
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe XbmcSql::File do
4
+ it { should belong_to :path }
5
+ it { should have_one :movie }
6
+
7
+ describe "attributes" do
8
+ subject { XbmcSql::File.first }
9
+
10
+ its(:id) { should eq 1 }
11
+ its(:filename) { should eq 'blow-the.grand.budapest.hotel.2014.720p.bluray.x264.mkv' }
12
+ its(:play_count) { should be_nil }
13
+ its(:last_played) { should be_nil }
14
+ its(:date_added) { should eq '2014-06-21 21:19:07' }
15
+ end
16
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ module XbmcSql
4
+ describe Movie do
5
+ it { should belong_to :set }
6
+ it { should belong_to :file }
7
+ it { should have_one :path }
8
+
9
+ let(:first_movie) { XbmcSql::Movie.first }
10
+
11
+ describe "attributes" do
12
+ subject { first_movie }
13
+
14
+ its(:id) { should eql 1 }
15
+ its(:title) { should eql "The Grand Budapest Hotel" }
16
+ its(:plot) { should match /GRAND BUDAPEST HOTEL recounts the adventures of Gustave/ }
17
+ its(:tagline) { should be_a String }
18
+ its(:rating_votes) { should eq "103,763" }
19
+ its(:writers) { should eq "Stefan Zweig / Wes Anderson" }
20
+ its(:year) { should eq '2014' }
21
+ its(:thumbnails) { should match /<thumb>/ }
22
+ its(:imdb_id) { should eq 'tt2278388' }
23
+ its(:sort_title) { should eq 'Grand Budapest Hotel' }
24
+ its(:runtime) { should eq '5940' }
25
+ its(:mpaa_rating) { should match /^Rated R/ }
26
+ its(:imdb_250) { should eq '138' }
27
+ its(:genre) { should match /Comedy/ }
28
+ its(:director) { should eq 'Wes Anderson' }
29
+ its(:original_title) { should eq 'The Grand Budapest Hotel' }
30
+ its(:studio) { should eq 'Fox Searchlight Pictures' }
31
+ its(:trailer_url) { should be_a String }
32
+ its(:fanart_urls) { should match /<fanart url/ }
33
+ its(:country) { should match /USA/ }
34
+ end
35
+
36
+ describe "#full_path" do
37
+ it "should join the full path + filename" do
38
+ expect(first_movie.full_path).to eq '/Users/jaiken/Movies/Movies/Grand Budapest Hotel, The (2014)/blow-the.grand.budapest.hotel.2014.720p.bluray.x264.mkv'
39
+ end
40
+ end
41
+
42
+ describe "#nfo_file" do
43
+ let(:likely) { '/Users/jaiken/Movies/Movies/Grand Budapest Hotel, The (2014)/movie.nfo' }
44
+ let(:bluray) { '/Users/jaiken/Movies/Movies/Grand Budapest Hotel, The (2014)/BDMV/STREAM/movie.nfo' }
45
+
46
+ context "when the nfo file is present" do
47
+ before { expect(::File).to receive(:exists?).with(likely).and_return true }
48
+
49
+ it "returns it" do
50
+ expect(first_movie.nfo_file).to eq likely
51
+ end
52
+ end
53
+
54
+ context "when it's a convulted bluray folder structure" do
55
+ before { expect(::File).to receive(:exists?).with(likely).and_return false }
56
+ before { expect(::File).to receive(:exists?).with(bluray).and_return true }
57
+
58
+ it "finds it" do
59
+ expect(first_movie.nfo_file).to eq bluray
60
+ end
61
+ end
62
+
63
+ context "when it's just not there" do
64
+ before { expect(::File).to receive(:exists?).with(likely).and_return false }
65
+ before { expect(::File).to receive(:exists?).with(bluray).and_return false }
66
+
67
+ it "returns nil" do
68
+ expect(first_movie.nfo_file).to be_nil
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "#update_nfo_file" do
74
+ context "when write_nfo_files is enabled" do
75
+ before { XbmcSql.stub(:write_nfo_files?).and_return true }
76
+
77
+ context "but no nfo file is found" do
78
+ before { ::File.stub(:exists?).and_return false }
79
+
80
+ it "doesn't try to write the nfo file" do
81
+ expect(NfoFile).not_to receive :new
82
+ first_movie.update_attributes! title: "New Title"
83
+ end
84
+ end
85
+
86
+ context "and the nfo file is found" do
87
+ before { ::File.stub(:exists?).and_return true }
88
+
89
+ let(:mock_file) { double(::File).as_null_object }
90
+ let(:mock_nfo) { double(NfoFile).as_null_object }
91
+
92
+ it "writes updated attributes to the nfo file" do
93
+ expect(::File).to receive(:open).and_return mock_file
94
+ expect(NfoFile).to receive(:new).with(mock_file).and_return mock_nfo
95
+
96
+ expect(mock_nfo).to receive(:title=).with 'New Title'
97
+ expect(mock_nfo).to receive :save!
98
+
99
+ first_movie.update_attributes! title: 'New Title'
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ context "when write_nfo_files? is disabled" do
106
+ before { XbmcSql.stub(:write_nfo_files?).and_return false }
107
+
108
+ it "doesn't even check for an nfo file" do
109
+ expect(::File).not_to receive :exists?
110
+ expect(NfoFile).not_to receive :new
111
+ first_movie.update_attributes! title: "New Title"
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe XbmcSql::Path do
4
+ it { should have_many :files }
5
+
6
+ describe "attributes" do
7
+ subject { XbmcSql::Path.first }
8
+
9
+ its(:id) { should eq 1 }
10
+ its(:path) { should eq '/Users/jaiken/Movies/Movies/' }
11
+ its(:content) { should eq 'movies' }
12
+ its(:scraper) { should be_a String }
13
+ its(:settings) { should match /^<settings>/ }
14
+ its(:use_folder_names) { should be_true }
15
+ its(:no_update) { should be_zero }
16
+ end
17
+
18
+ describe "#is_samba?" do
19
+ let(:not_samba) { create :path, path: 'file://some_path/file.mkv' }
20
+ let(:yes_samba) { create :path, path: 'smb://some_server' }
21
+
22
+ it "is true if it is" do
23
+ expect(not_samba).not_to be_is_samba
24
+ end
25
+
26
+ it "is true if it is" do
27
+ expect(yes_samba).to be_is_samba
28
+ end
29
+ end
30
+
31
+ describe "#mapped_path" do
32
+ let(:original_path) { 'smb://192.168.1.8/Video/Movies/Some Movie (2014)/some_movie.mp4' }
33
+ let(:network_path) { create :path, path: original_path }
34
+
35
+ context "when there's no path substitions" do
36
+ it "returns the path as-is" do
37
+ expect(network_path.mapped_path).to eq original_path
38
+ end
39
+ end
40
+
41
+ context "when there are path substitions" do
42
+ before { XbmcSql.stub(:path_mappings).and_return "smb://192.168.1.8/Video" => "/Volumes/Video"}
43
+
44
+ it "returns the path modified to reflect this" do
45
+ expect(network_path.mapped_path).to eq '/Volumes/Video/Movies/Some Movie (2014)/some_movie.mp4'
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe XbmcSql::Set do
4
+ it { should have_many :movies }
5
+ end
@@ -0,0 +1,23 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ require 'factory_girl_rails'
4
+ require File.expand_path("../../spec/test_app/config/environment", __FILE__)
5
+ require 'rspec/rails'
6
+ require 'shoulda-matchers'
7
+
8
+ require 'coveralls'
9
+ Coveralls.wear!
10
+
11
+ Dir[Rails.root.join("../../spec/support/**/*.rb")].each {|f| require f}
12
+ Dir[Rails.root.join("../../spec/factories/**/*.rb")].each {|f| require f}
13
+
14
+ RSpec.configure do |config|
15
+ config.include FactoryGirl::Syntax::Methods
16
+
17
+ config.filter_run focus: true
18
+ config.run_all_when_everything_filtered = true
19
+
20
+ config.use_transactional_fixtures = true
21
+ config.infer_base_class_for_anonymous_controllers = false
22
+ config.order = 'random'
23
+ end
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
+ load Gem.bin_path('bundler', 'bundle')
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../config/boot'
3
+ require 'rake'
4
+ Rake.application.run
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Rails.application