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,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'