xbmc-sql 0.0.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.
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