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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e1e7454321ab490713fde28f20d532446e47097d
4
+ data.tar.gz: a718ec7e5f0f7cadc6f8dedfdc9ac993112e217c
5
+ SHA512:
6
+ metadata.gz: ac86e720ca8661218cc07f93173bfb4d7d7add86b68f187b40eeb24e762b38cc07cae51645cd0fb423890be39b27e0bd8d09105b9ef503ba9b6b97450c266ff9
7
+ data.tar.gz: 2e9bab8fdbd41706b80d180585e94eb5fa2ff63c89e091f81040e377daf9fac2bb64bc8b9b66b97264d9420f74949441d6c488052682c48e9e260e576a84f093
@@ -0,0 +1,17 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ spec/test_app/db/*.sqlite3-journal
5
+ spec/test_app/db/*.db
6
+ spec/test_app/log/*.log
7
+ spec/test_app/tmp/
8
+ spec/test_app/.sass-cache
9
+
10
+ Gemfile.lock
11
+ .rvmrc
12
+
13
+ tmp/
14
+
15
+ *.sql.gz
16
+
17
+ coverage/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - 2.1.5
7
+ - 2.2.0
8
+ matrix:
9
+ allow_failures:
10
+ - rvm: 1.9.3
11
+ env:
12
+ - "RAILS_VERSION=4.0.0"
13
+ - "RAILS_VERSION=4.1.0"
14
+ - "RAILS_VERSION=4.2.0"
15
+ notifications:
16
+ email:
17
+ recipients:
18
+ - 60tonangel@gmail.com
19
+ on_success: change
20
+ on_failure: change
@@ -0,0 +1,5 @@
1
+ # 0.0.2
2
+ * Feature: Support Rails 4.0, 4.1, and 4.2. Test against supported Rails versions.
3
+
4
+ # 0.0.1
5
+ * Initial Release
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ rails_version = ENV["RAILS_VERSION"] || '4.1.0'
4
+ rails = "~> #{rails_version}"
5
+
6
+ gem 'test-unit' if rails_version == '4.0.0' # https://github.com/rspec/rspec-rails/issues/1273
7
+ gem "rails", rails
8
+
9
+ gemspec
@@ -0,0 +1,13 @@
1
+ guard :rspec, all_after_pass: false, all_on_start: false, failed_mode: :none, cmd: 'SIMPLECOV=false rspec --color --no-profile --format progress' do
2
+
3
+ # Run all tests if these change:
4
+ watch('spec/spec_helper.rb') { 'spec' }
5
+ watch(%r{^spec/support/(.+)\.rb$}) { 'spec' }
6
+
7
+ # Any spec runs itself:
8
+ watch(%r{^spec/.+_spec\.rb$})
9
+
10
+ # app/foo runs spec/foo, lib/foo runs spec/lib/foo...
11
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
12
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
13
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Justin Aiken
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,92 @@
1
+ [![Build Status](http://img.shields.io/travis/JustinAiken/xbmc_sql/master.svg)](http://travis-ci.org/JustinAiken/xbmc_sql) [![Coveralls branch](http://img.shields.io/coveralls/JustinAiken/xbmc_sql/master.svg)](https://coveralls.io/r/JustinAiken/xbmc_sql?branch=master)[![Code Climate](http://img.shields.io/codeclimate/github/JustinAiken/xbmc_sql.svg)](https://codeclimate.com/github/JustinAiken/xbmc_sql)
2
+
3
+ # xbmc_sql
4
+
5
+ xbmc_sql is a Rails engine for interacting with the XBMC/Kodi database directly. It can also update .nfo files as it makes changes to the database.
6
+
7
+ Special thanks to [Rocketmade](http://www.rocketmade.com/) for development resources.
8
+
9
+ ## Requirements/Support
10
+
11
+ - Rails
12
+ - Supported:
13
+ - 4.0
14
+ - 4.1
15
+ - 4.2
16
+ - XBMC 13 (Gotham) or Kodi 14 (Helix)
17
+ - sqlite or mysql database reachable by the Rails application
18
+
19
+ ## Setup
20
+
21
+ #### Database
22
+
23
+ In your database.yml, set up an `xbmc_development` (or whatever environment) seperate than the other database:
24
+
25
+ ```yaml
26
+ development:
27
+ adapter: mysql2
28
+ database: some_other_database
29
+ username: boring_stuff
30
+ password: foo
31
+
32
+ xbmc_development:
33
+ adapter: mysql2
34
+ database: xbmc
35
+ username: xbmc_user
36
+ password: xbmc_pass
37
+ ```
38
+
39
+ #### Configuration
40
+
41
+ ```ruby
42
+ XbmcSql.setup do |x|
43
+ # Write .nfo files when matching db record is updated
44
+ x.write_nfo_files = true # Defaults to false
45
+
46
+ # Setup a path mapping
47
+ #
48
+ # This is useful if you use have the movies mounted in share
49
+ # By default there are no mappings mapped
50
+ x.path_mappings = {
51
+ 'smb://my_nas/' => '/Volumes/Video'
52
+ }
53
+ end
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ##### Movies
59
+ ```ruby
60
+ movie = XbmcSql::Movie.first
61
+ movie.title # -> "Seven Samurai"
62
+ movie.genre # -> "Action / Drama"
63
+
64
+ movie.genre = "Action / Drama / History"
65
+ movie.save!
66
+ # At this point, the movie is updated in the database.
67
+ # If write .nfo files are on, the .nfo file would also be updated
68
+ ```
69
+
70
+ ##### Sets
71
+
72
+ ```ruby
73
+ set = XbmcSql::Set.first
74
+ set.name # -> "AK100"
75
+ set.movies.map { |movie| movie.name } # -> ["Seven Samurai", "Yojimbo",... ]
76
+ ```
77
+
78
+ ##### Built-in tools
79
+
80
+ There are a couple of useful rake tasks:
81
+
82
+ ```bash
83
+ # Update the imdb top 250 status of all movies:
84
+ rake xbmc_sql:update:top_250
85
+
86
+ # Update the imdb rating for all movies:
87
+ rake xbmc_sql:update:ratings
88
+ ```
89
+
90
+ ## License
91
+
92
+ MIT
@@ -0,0 +1,49 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'XbmcSql'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include 'README.markdown'
14
+ rdoc.rdoc_files.include 'lib/**/*.rb'
15
+ end
16
+
17
+ require 'rspec/core/rake_task'
18
+ RSpec::Core::RakeTask.new(:spec) do |t|
19
+ end
20
+
21
+ desc "Run tests for CI"
22
+ task :default do
23
+ Rake::Task["db:bootstrap"].invoke
24
+ Rake::Task["spec"].invoke
25
+ end
26
+
27
+ namespace :db do
28
+ desc "Wipe development/test db's and replace with seed copy"
29
+ task :bootstrap do
30
+ DB_PATH = "spec/test_app/db/"
31
+ TEMPLATE = "fresh_db.sqlite3"
32
+ DEV_DB = "development.db"
33
+ TEST_DB = "test.db"
34
+
35
+ system *%W[rm -f #{DB_PATH}#{DEV_DB}]
36
+ system *%W[rm -f #{DB_PATH}#{TEST_DB}]
37
+ system *%W[cp #{DB_PATH}#{TEMPLATE} #{DB_PATH}#{DEV_DB}]
38
+ system *%W[cp #{DB_PATH}#{TEMPLATE} #{DB_PATH}#{TEST_DB}]
39
+ end
40
+ end
41
+
42
+ APP_RAKEFILE = File.expand_path("../spec/test_app/Rakefile", __FILE__)
43
+ load 'rails/tasks/engine.rake'
44
+
45
+ unless defined?(Thor) && defined?(Thor::Base)
46
+ require 'thor'
47
+ end
48
+
49
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,45 @@
1
+ module XbmcSql
2
+ class Base < ActiveRecord::Base
3
+ self.abstract_class = true
4
+
5
+ establish_connection XbmcSql::DATABASE
6
+
7
+ self.record_timestamps = false
8
+
9
+ class << self
10
+ attr_accessor :aliased_attrs
11
+ @aliased_attrs = {}
12
+ end
13
+
14
+ def self.alias_attributes(attrs)
15
+ @aliased_attrs = attrs
16
+ attrs.each { |k, v| self.alias_attribute v, k }
17
+ end
18
+
19
+ def attributes
20
+ super.inject({}) do |hash, kv|
21
+ if aliased_attrs.keys.include? kv[0].to_sym
22
+ hash[aliased_attrs[kv[0].to_sym].to_s] = kv[1].to_s
23
+ else
24
+ hash[kv[0]] = kv[1]
25
+ end
26
+
27
+ hash
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def aliased_attrs
34
+ self.class.aliased_attrs
35
+ end
36
+
37
+ def aliased_changes
38
+ Hash[changes.map { |k, v| [(aliased_attrs[k.to_sym] || k).to_s, v] }]
39
+ end
40
+
41
+ def aliased_changed
42
+ changed.map { |k| (aliased_attrs[k.to_sym] || k).to_s }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,17 @@
1
+ module XbmcSql
2
+ class File < Base
3
+ self.table_name = :files
4
+
5
+ belongs_to :path, foreign_key: :idPath
6
+ has_one :movie, foreign_key: :idFile
7
+
8
+ alias_attributes(
9
+ idFile: :id,
10
+ strFilename: :filename,
11
+ playCount: :play_count,
12
+ lastPlayed: :last_played,
13
+ dateAdded: :date_added
14
+ )
15
+
16
+ end
17
+ end
@@ -0,0 +1,78 @@
1
+ module XbmcSql
2
+ class Movie < Base
3
+ self.table_name = :movie
4
+
5
+ belongs_to :set, foreign_key: :idSet
6
+ belongs_to :file, foreign_key: :idFile
7
+ has_one :path, through: :file
8
+
9
+ after_update :update_nfo_file, if: ->(movie) { XbmcSql.write_nfo_files? && movie.has_nfo_file? }
10
+
11
+ alias_attributes(
12
+ idMovie: :id,
13
+ c00: :title,
14
+ c01: :plot,
15
+ c02: :plot_outline,
16
+ c03: :tagline,
17
+ c04: :rating_votes,
18
+ c05: :rating,
19
+ c06: :writers,
20
+ c07: :year,
21
+ c08: :thumbnails,
22
+ c09: :imdb_id,
23
+ c10: :sort_title,
24
+ c11: :runtime,
25
+ c12: :mpaa_rating,
26
+ c13: :imdb_250,
27
+ c14: :genre,
28
+ c15: :director,
29
+ c16: :original_title,
30
+ # c17: :unknown,
31
+ c18: :studio,
32
+ c19: :trailer_url,
33
+ c20: :fanart_urls,
34
+ c21: :country
35
+ # c23: :path_id
36
+ )
37
+
38
+ scope :in_top_250, -> { where 'c13 IS NOT NULL AND c13 != ?', '0' }
39
+ scope :with_imdb_id, ->imdb_id { where imdb_id: imdb_id }
40
+
41
+ def full_path
42
+ if XbmcSql.use_path_mappings?
43
+ "#{path.mapped_path}#{file.filename}"
44
+ else
45
+ "#{path.path}#{file.filename}"
46
+ end
47
+ end
48
+
49
+ def nfo_file
50
+ if XbmcSql.use_path_mappings?
51
+ likely_path = "#{path.mapped_path}movie.nfo"
52
+ else
53
+ likely_path = "#{path.path}movie.nfo"
54
+ end
55
+
56
+ if ::File.exists? likely_path
57
+ return likely_path
58
+ else
59
+ likely_path.gsub! /movie.nfo$/, 'BDMV/STREAM/movie.nfo'
60
+ return likely_path if ::File.exists? likely_path
61
+ nil
62
+ end
63
+ end
64
+
65
+ def has_nfo_file?
66
+ nfo_file.present?
67
+ end
68
+
69
+ def update_nfo_file
70
+ NfoFile.new(::File.open nfo_file).tap do |nfo|
71
+ aliased_changes.each do |change, values|
72
+ nfo.send "#{change}=", values[1]
73
+ end
74
+ nfo.save!
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,33 @@
1
+ module XbmcSql
2
+ class Path < Base
3
+ self.table_name = :path
4
+
5
+ has_many :files, foreign_key: :idPath
6
+
7
+ alias_attributes(
8
+ idPath: :id,
9
+ strPath: :path,
10
+ strContent: :content,
11
+ strScraper: :scraper,
12
+ # strHash: :unused,
13
+ # scanRecursive: :unused,
14
+ useFolderNames: :use_folder_names,
15
+ strSettings: :settings,
16
+ noUpdate: :no_update,
17
+ # exclude: :exclude,
18
+ dateAdded: :created_at
19
+ )
20
+
21
+ def is_samba?
22
+ path =~ /^smb/
23
+ end
24
+
25
+ def mapped_path
26
+ self.path.tap do |original_path|
27
+ XbmcSql.path_mappings.each do |original, change|
28
+ original_path.gsub! original, change
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ module XbmcSql
2
+ class Set < Base
3
+ self.table_name = :sets
4
+
5
+ has_many :movies, foreign_key: :idSet
6
+
7
+ alias_attributes idSet: :id, strSet: :name
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/xbmc_sql/engine', __FILE__)
6
+
7
+ # Set up gems listed in the Gemfile.
8
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
9
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
10
+
11
+ require 'rails/all'
12
+ require 'rails/engine/commands'