tivohmo 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG +30 -0
- data/Gemfile +2 -0
- data/README.md +4 -6
- data/TODO +1 -0
- data/contrib/tivohmo.conf +2 -2
- data/contrib/tivohmo.plist +1 -1
- data/contrib/tivohmo.yml +60 -0
- data/lib/tivohmo/adapters/filesystem/file_item.rb +2 -3
- data/lib/tivohmo/adapters/plex/category.rb +87 -6
- data/lib/tivohmo/adapters/plex/episode.rb +30 -11
- data/lib/tivohmo/adapters/plex/group.rb +20 -0
- data/lib/tivohmo/adapters/plex/movie.rb +15 -3
- data/lib/tivohmo/adapters/plex/qualified_category.rb +14 -3
- data/lib/tivohmo/adapters/plex/season.rb +2 -2
- data/lib/tivohmo/adapters/plex/section.rb +5 -5
- data/lib/tivohmo/adapters/plex/transcoder.rb +5 -1
- data/lib/tivohmo/adapters/plex.rb +1 -0
- data/lib/tivohmo/adapters/settings/application.rb +37 -0
- data/lib/tivohmo/adapters/settings/display_item.rb +35 -0
- data/lib/tivohmo/adapters/settings/key_container.rb +35 -0
- data/lib/tivohmo/adapters/settings/metadata.rb +26 -0
- data/lib/tivohmo/adapters/settings/reset_defaults_item.rb +39 -0
- data/lib/tivohmo/adapters/settings/set_value_item.rb +38 -0
- data/lib/tivohmo/adapters/settings/transcoder.rb +23 -0
- data/lib/tivohmo/adapters/settings.rb +7 -0
- data/lib/tivohmo/adapters/streamio/transcoder.rb +39 -1
- data/lib/tivohmo/api/container.rb +5 -1
- data/lib/tivohmo/api/item.rb +2 -0
- data/lib/tivohmo/api/subtitle.rb +13 -0
- data/lib/tivohmo/api/transcoder.rb +1 -3
- data/lib/tivohmo/api.rb +1 -0
- data/lib/tivohmo/beacon.rb +3 -3
- data/lib/tivohmo/cli.rb +175 -48
- data/lib/tivohmo/config.rb +157 -0
- data/lib/tivohmo/server/views/_container.builder +1 -1
- data/lib/tivohmo/server.rb +6 -3
- data/lib/tivohmo/version.rb +1 -1
- data/lib/tivohmo.rb +1 -0
- data/spec/adapters/filesystem/file_item_spec.rb +1 -1
- data/spec/adapters/plex/application_spec.rb +10 -1
- data/spec/adapters/plex/category_spec.rb +93 -20
- data/spec/adapters/plex/episode_spec.rb +34 -15
- data/spec/adapters/plex/metadata_spec.rb +5 -7
- data/spec/adapters/plex/movie_spec.rb +10 -7
- data/spec/adapters/plex/qualified_category_spec.rb +17 -17
- data/spec/adapters/plex/season_spec.rb +23 -4
- data/spec/adapters/plex/section_spec.rb +4 -4
- data/spec/adapters/plex/show_spec.rb +19 -4
- data/spec/adapters/plex/transcoder_spec.rb +2 -8
- data/spec/adapters/settings/application_spec.rb +25 -0
- data/spec/adapters/settings/display_item_spec.rb +29 -0
- data/spec/adapters/settings/key_container_spec.rb +33 -0
- data/spec/adapters/settings/metadata_spec.rb +33 -0
- data/spec/adapters/settings/reset_defaults_item_spec.rb +54 -0
- data/spec/adapters/settings/set_value_item_spec.rb +54 -0
- data/spec/api/container_spec.rb +12 -0
- data/spec/api/item_spec.rb +2 -0
- data/spec/api/transcoder_spec.rb +0 -1
- data/spec/beacon_spec.rb +3 -1
- data/spec/cli_spec.rb +57 -19
- data/spec/config_spec.rb +224 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Application/_children/should_get_children.yml +61 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_children/should_allow_disabling_subtitles.yml +424 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_children/should_display_non-zero_child_count_once_children_fetched.yml +653 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_children/should_have_children.yml +599 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_children/should_have_children_with_embedded_subtitles.yml +595 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_children/should_have_children_with_subtitles.yml +482 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_children/should_memoize.yml +478 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_children/should_refresh_children_when_config_changes.yml +1245 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_children/should_use_category_value_for_children.yml +395 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_initialize/should_instantiate.yml +61 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_initialize/should_set_presorted_if_present.yml +61 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Category/_initialize/should_use_category_value_for_title_if_present.yml +61 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Episode/_initialize/should_instantiate.yml +444 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Episode/_metadata/should_allow_disabling_series_id_in_metadata.yml +444 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Episode/_metadata/should_populate_metadata.yml +579 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Metadata/_initialize/should_instantiate.yml +296 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Movie/_initialize/should_instantiate.yml +296 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Movie/_metadata/should_populate_metadata.yml +296 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_QualifiedCategory/_children/should_display_non-zero_child_count_once_children_fetched.yml +220 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_QualifiedCategory/_children/should_have_children.yml +393 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_QualifiedCategory/_children/should_memoize.yml +219 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_QualifiedCategory/_initialize/should_instantiate.yml +61 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Season/_children/should_have_children.yml +444 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Season/_children/should_memoize.yml +444 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Season/_initialize/should_instantiate.yml +250 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Section/_children/should_have_category_children.yml +61 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Section/_children/should_memoize.yml +61 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Section/_initialize/should_instantiate.yml +61 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Show/_children/should_have_children.yml +250 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Show/_children/should_memoize.yml +250 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Show/_initialize/should_instantiate.yml +166 -0
- data/spec/fixtures/vcr/TivoHMO_Adapters_Plex_Transcoder/_initialize/should_instantiate.yml +296 -0
- data/spec/server_spec.rb +31 -2
- data/spec/spec_helper.rb +24 -36
- data/tivohmo.gemspec +2 -2
- metadata +109 -3
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
|
3
|
+
module TivoHMO
|
4
|
+
|
5
|
+
class Config
|
6
|
+
include GemLogger::LoggerSupport
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
@primary_data = Data.new
|
12
|
+
@secondary_data = Data.new
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def setup(primary_filename, secondary_filename=nil)
|
17
|
+
@primary_file = primary_filename
|
18
|
+
@secondary_file = secondary_filename
|
19
|
+
|
20
|
+
@primary_data = Data.new
|
21
|
+
@secondary_data = Data.new
|
22
|
+
|
23
|
+
if File.exist?(@primary_file.to_s)
|
24
|
+
logger.info "Loading primary config from: '#{@primary_file}'"
|
25
|
+
@primary_data = Data.load(@primary_file)
|
26
|
+
else
|
27
|
+
logger.info "No primary config at file: '#{@primary_file}'"
|
28
|
+
end
|
29
|
+
|
30
|
+
# get secondary config from primary if present and not set explictly
|
31
|
+
secondary = get(:settings)
|
32
|
+
@secondary_file ||= File.expand_path(secondary) if secondary
|
33
|
+
|
34
|
+
if File.exist?(@secondary_file.to_s)
|
35
|
+
logger.info "Loading secondary config from: '#{@secondary_file}'"
|
36
|
+
@secondary_data = Data.load(@secondary_file)
|
37
|
+
else
|
38
|
+
logger.info "No secondary config at file: '#{@secondary_file}'"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def reset
|
43
|
+
@primary_file = @secondary_file = nil
|
44
|
+
@primary_data = @secondary_data = nil
|
45
|
+
@known_config = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def known_config
|
49
|
+
@known_config ||= {}
|
50
|
+
end
|
51
|
+
|
52
|
+
def get(scoped_key)
|
53
|
+
scoped_key = Array(scoped_key)
|
54
|
+
result = nil
|
55
|
+
|
56
|
+
key = scoped_key.pop
|
57
|
+
path = scoped_key
|
58
|
+
(0..path.size).to_a.reverse.each do |i|
|
59
|
+
partial = path[0, i] << key
|
60
|
+
|
61
|
+
begin
|
62
|
+
result = @secondary_data.deep_fetch(*partial)
|
63
|
+
rescue Data::UndefinedPathError
|
64
|
+
begin
|
65
|
+
result = @primary_data.deep_fetch(*partial)
|
66
|
+
rescue Data::UndefinedPathError
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
break if ! result.nil?
|
71
|
+
end
|
72
|
+
|
73
|
+
if result.nil?
|
74
|
+
registered = known_config[key]
|
75
|
+
result = registered[:default_value] if registered
|
76
|
+
end
|
77
|
+
|
78
|
+
result
|
79
|
+
end
|
80
|
+
|
81
|
+
def set(scoped_key, value, persist=true)
|
82
|
+
scoped_key = Array(scoped_key)
|
83
|
+
key = scoped_key.pop
|
84
|
+
|
85
|
+
val_hash = {key => value}
|
86
|
+
scoped_key.reverse.each do |k|
|
87
|
+
val_hash = {k => val_hash}
|
88
|
+
end
|
89
|
+
|
90
|
+
@secondary_data = @secondary_data.deep_merge(val_hash)
|
91
|
+
File.write(@secondary_file, YAML.dump(@secondary_data)) if persist && @secondary_file
|
92
|
+
|
93
|
+
registered = known_config[key]
|
94
|
+
if registered && registered[:on_change]
|
95
|
+
registered[:on_change].call
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class Data < ::Hash
|
100
|
+
include Hashie::Extensions::IndifferentAccess
|
101
|
+
include Hashie::Extensions::DeepFetch
|
102
|
+
|
103
|
+
def self.load(filename)
|
104
|
+
h = Hashie::Extensions::Parsers::YamlErbParser.perform(filename)
|
105
|
+
new.replace(h)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
module Mixin
|
110
|
+
extend ActiveSupport::Concern
|
111
|
+
|
112
|
+
included do
|
113
|
+
delegate :config_register,
|
114
|
+
:config_get,
|
115
|
+
:config_set,
|
116
|
+
:to => "self.class"
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
module ClassMethods
|
121
|
+
|
122
|
+
def config_register(key, default_value, description, &on_change_block)
|
123
|
+
raise ArgumentError, "Config '#{key}' already registered" if Config.instance.known_config[key]
|
124
|
+
|
125
|
+
Config.instance.known_config[key] = {
|
126
|
+
default_value: default_value,
|
127
|
+
description: description,
|
128
|
+
source_path: config_path,
|
129
|
+
on_change: on_change_block
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
def config_get(key)
|
134
|
+
scoped_key = config_path << key
|
135
|
+
result = Config.instance.get(scoped_key)
|
136
|
+
result
|
137
|
+
end
|
138
|
+
|
139
|
+
def config_set(key, value)
|
140
|
+
Config.instance.set(key, value)
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def config_path
|
146
|
+
path = self.name.underscore
|
147
|
+
path = path.sub(/.*tivo_hmo\//, '')
|
148
|
+
pieces = path.split('/')
|
149
|
+
pieces
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
@@ -5,7 +5,7 @@ xml.Item do
|
|
5
5
|
xml.ContentType container.content_type
|
6
6
|
xml.SourceFormat container.source_format
|
7
7
|
xml.UniqueId format_uuid(container.uuid)
|
8
|
-
xml.TotalItems container.
|
8
|
+
xml.TotalItems container.child_count
|
9
9
|
xml.LastCaptureDate format_date(container.created_at) if container.created_at
|
10
10
|
end
|
11
11
|
|
data/lib/tivohmo/server.rb
CHANGED
@@ -12,6 +12,10 @@ module TivoHMO
|
|
12
12
|
# tivo format
|
13
13
|
class Server < Sinatra::Base
|
14
14
|
include GemLogger::LoggerSupport
|
15
|
+
include TivoHMO::Config::Mixin
|
16
|
+
|
17
|
+
config_register(:force_grouping, true,
|
18
|
+
"Force groups/folders regardless of parameters supplied by the tivo request")
|
15
19
|
|
16
20
|
disable :logging
|
17
21
|
set :root, File.expand_path("../server", __FILE__)
|
@@ -211,8 +215,7 @@ module TivoHMO
|
|
211
215
|
item_count = (params['ItemCount'] || 8).to_i
|
212
216
|
|
213
217
|
# Yes or No, default no
|
214
|
-
|
215
|
-
recurse = false #(params['Recurse'] == 'Yes')
|
218
|
+
recurse = config_get(:force_grouping) ? false : (params['Recurse'] == 'Yes')
|
216
219
|
|
217
220
|
# csv of Type, Title, CreationDate, LastChangeDate, Random
|
218
221
|
# reverse with preceding !
|
@@ -250,7 +253,7 @@ module TivoHMO
|
|
250
253
|
|
251
254
|
children = select_all_items(children) if recurse
|
252
255
|
|
253
|
-
children = sort(children, sort_order) if sort_order
|
256
|
+
children = sort(children, sort_order) if sort_order && ! container.presorted
|
254
257
|
|
255
258
|
if anchor_item
|
256
259
|
anchor = server.find(anchor_item)
|
data/lib/tivohmo/version.rb
CHANGED
data/lib/tivohmo.rb
CHANGED
@@ -20,7 +20,7 @@ describe TivoHMO::Adapters::Filesystem::FileItem do
|
|
20
20
|
file = __FILE__
|
21
21
|
subject = described_class.new(file)
|
22
22
|
expect(subject).to be_a described_class
|
23
|
-
expect(subject.
|
23
|
+
expect(subject.file).to eq File.expand_path(file)
|
24
24
|
expect(subject.title).to eq File.basename(file)
|
25
25
|
expect(subject.modified_at).to_not be_nil
|
26
26
|
expect(subject.created_at).to_not be_nil
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative "../../spec_helper"
|
2
2
|
require 'tivohmo/adapters/plex'
|
3
3
|
|
4
|
-
describe TivoHMO::Adapters::Plex::Application do
|
4
|
+
describe TivoHMO::Adapters::Plex::Application, :vcr do
|
5
5
|
|
6
6
|
|
7
7
|
describe "#initialize" do
|
@@ -17,4 +17,13 @@ describe TivoHMO::Adapters::Plex::Application do
|
|
17
17
|
|
18
18
|
end
|
19
19
|
|
20
|
+
describe "#children" do
|
21
|
+
|
22
|
+
it "should get children" do
|
23
|
+
app = described_class.new('localhost')
|
24
|
+
expect(app.children).to_not be_empty
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
20
29
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require_relative "../../spec_helper"
|
2
2
|
require 'tivohmo/adapters/plex'
|
3
3
|
|
4
|
-
describe TivoHMO::Adapters::Plex::Category do
|
4
|
+
describe TivoHMO::Adapters::Plex::Category, :vcr do
|
5
5
|
|
6
|
-
let(:plex_delegate) {
|
6
|
+
let(:plex_delegate) { plex_movie_section }
|
7
7
|
|
8
8
|
describe "#initialize" do
|
9
9
|
|
@@ -15,9 +15,10 @@ describe TivoHMO::Adapters::Plex::Category do
|
|
15
15
|
expect(category).to be_a TivoHMO::API::Container
|
16
16
|
expect(category.category_type).to eq(:newest)
|
17
17
|
expect(category.category_value).to be_nil
|
18
|
+
expect(category.presorted).to eq(false)
|
18
19
|
expect(category.title).to eq('Newest')
|
19
20
|
expect(category.identifier).to eq(plex_delegate.key)
|
20
|
-
expect(category.modified_at).to eq(Time.at(plex_delegate.updated_at))
|
21
|
+
expect(category.modified_at).to eq(Time.at(plex_delegate.updated_at.to_i))
|
21
22
|
expect(category.created_at).to eq(now)
|
22
23
|
end
|
23
24
|
|
@@ -31,38 +32,110 @@ describe TivoHMO::Adapters::Plex::Category do
|
|
31
32
|
expect(category.title).to eq('MyTitle')
|
32
33
|
end
|
33
34
|
|
35
|
+
it "should set presorted if present" do
|
36
|
+
cval = {title: 'MyTitle', key: '/plex/key'}
|
37
|
+
category = described_class.new(plex_delegate, :by_year, nil, true)
|
38
|
+
expect(category.presorted).to eq(true)
|
39
|
+
end
|
40
|
+
|
34
41
|
end
|
35
42
|
|
36
43
|
describe "#children" do
|
37
44
|
|
38
45
|
it "should memoize" do
|
39
|
-
listing = [plex_stub(::Plex::Movie, originally_available_at: "2013-01-02")]
|
40
|
-
allow(plex_delegate).to receive(:newest).and_return(listing)
|
41
46
|
section = described_class.new(plex_delegate, :newest)
|
42
47
|
expect(section.children.object_id).to eq(section.children.object_id)
|
43
48
|
end
|
44
49
|
|
45
50
|
it "should have children" do
|
46
|
-
listing = [
|
47
|
-
plex_stub(::Plex::Movie, originally_available_at: "2013-01-02"),
|
48
|
-
plex_stub(::Plex::Episode, originally_available_at: "2013-01-02"),
|
49
|
-
plex_stub(::Plex::Show)
|
50
|
-
]
|
51
|
-
allow(plex_delegate).to receive(:newest).and_return(listing)
|
52
51
|
section = described_class.new(plex_delegate, :newest)
|
53
|
-
|
52
|
+
|
53
|
+
expect(section.children.size).to_not be(0)
|
54
|
+
|
55
|
+
keys = section.children.collect(&:delegate).collect(&:key)
|
56
|
+
expected_keys = plex_delegate.newest.collect(&:key)
|
57
|
+
expect(keys).to include(*expected_keys)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should display non-zero child_count once children fetched" do
|
61
|
+
section = described_class.new(plex_delegate, :newest)
|
62
|
+
|
63
|
+
expect(section.child_count).to be(0)
|
64
|
+
section.children
|
65
|
+
expect(section.child_count).to_not be(0)
|
66
|
+
expect(section.child_count).to eq(section.children.size)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should have children with subtitles" do
|
70
|
+
section = described_class.new(plex_delegate, :newest)
|
71
|
+
|
72
|
+
subgroup = section.children.find {|c| c.is_a?(TivoHMO::Adapters::Plex::Group) }
|
73
|
+
expect(subgroup).to_not be_nil
|
74
|
+
primary = subgroup.children[0]
|
75
|
+
sub = subgroup.children[1]
|
76
|
+
expect(primary.title).to_not match(/sub\]/)
|
77
|
+
expect(sub.title).to match(primary.title)
|
78
|
+
expect(sub.title).to match(/sub\]/)
|
79
|
+
expect(sub.subtitle.language).to_not be_nil
|
80
|
+
expect(sub.subtitle.language_code).to_not be_nil
|
81
|
+
expect(sub.subtitle.location).to_not be_nil
|
82
|
+
|
83
|
+
withoutsub = section.children.find {|c| ! c.is_a?(TivoHMO::Adapters::Plex::Group) }
|
84
|
+
expect(withoutsub).to_not be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should have children with embedded subtitles" do
|
88
|
+
section = described_class.new(plex_delegate, :newest)
|
89
|
+
|
90
|
+
subgroup = section.children.find {|c|
|
91
|
+
c.is_a?(TivoHMO::Adapters::Plex::Group) &&
|
92
|
+
c.children.any? {|m| m.subtitle && m.subtitle.language == 'Embedded' }
|
93
|
+
}
|
94
|
+
expect(subgroup).to_not be_nil
|
95
|
+
primary = subgroup.children[0]
|
96
|
+
sub = subgroup.children[1]
|
97
|
+
expect(primary.title).to_not match(/sub\]/)
|
98
|
+
expect(sub.title).to match(primary.title)
|
99
|
+
expect(sub.title).to match(/sub\]/)
|
100
|
+
expect(sub.subtitle.language).to eq('Embedded')
|
101
|
+
expect(sub.subtitle.language_code).to_not be_nil
|
102
|
+
expect(sub.subtitle.location).to eq(0)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should allow disabling subtitles" do
|
106
|
+
section = described_class.new(plex_delegate, :newest)
|
107
|
+
described_class.config_set(:enable_subtitles, false)
|
108
|
+
withsub = section.children.find {|c| c.is_a?(TivoHMO::Adapters::Plex::Group) }
|
109
|
+
expect(withsub).to be_nil
|
54
110
|
end
|
55
111
|
|
112
|
+
it "should refresh children when config changes" do
|
113
|
+
described_class.config_set(:enable_subtitles, false)
|
114
|
+
section = described_class.new(plex_delegate, :newest)
|
115
|
+
|
116
|
+
withsub = section.children.select {|c| c.is_a?(TivoHMO::Adapters::Plex::Group) }
|
117
|
+
withoutsub = section.children.select {|c| ! c.is_a?(TivoHMO::Adapters::Plex::Group) }
|
118
|
+
expect(withsub).to be_empty
|
119
|
+
expect(withoutsub).to_not be_empty
|
120
|
+
|
121
|
+
described_class.config_set(:enable_subtitles, true)
|
122
|
+
|
123
|
+
withsub = section.children.select {|c| c.is_a?(TivoHMO::Adapters::Plex::Group) }
|
124
|
+
withoutsub = section.children.select {|c| ! c.is_a?(TivoHMO::Adapters::Plex::Group) }
|
125
|
+
expect(withsub).to_not be_empty
|
126
|
+
expect(withoutsub).to_not be_empty
|
127
|
+
end
|
128
|
+
|
129
|
+
|
56
130
|
it "should use category_value for children" do
|
57
|
-
|
58
|
-
plex_stub(::Plex::Movie, originally_available_at: "2013-01-02"),
|
59
|
-
plex_stub(::Plex::Episode, originally_available_at: "2013-01-02"),
|
60
|
-
plex_stub(::Plex::Show)
|
61
|
-
]
|
62
|
-
cval = {title: 'Title', key: 'key'}
|
63
|
-
allow(plex_delegate).to receive(:by_year).with('key').and_return(listing)
|
131
|
+
cval = plex_delegate.years.first
|
64
132
|
section = described_class.new(plex_delegate, :by_year, cval)
|
65
|
-
|
133
|
+
|
134
|
+
expect(section.children.size).to_not be(0)
|
135
|
+
|
136
|
+
keys = section.children.collect(&:delegate).collect(&:key)
|
137
|
+
expected_keys = plex_delegate.by_year(cval[:key]).collect(&:key)
|
138
|
+
expect(keys).to include(*expected_keys)
|
66
139
|
end
|
67
140
|
|
68
141
|
end
|
@@ -1,15 +1,14 @@
|
|
1
1
|
require_relative "../../spec_helper"
|
2
2
|
require 'tivohmo/adapters/plex'
|
3
3
|
|
4
|
-
describe TivoHMO::Adapters::Plex::Episode do
|
4
|
+
describe TivoHMO::Adapters::Plex::Episode, :vcr do
|
5
5
|
|
6
|
-
let(:plex_delegate) {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
originally_available_at: "2014-06-04") }
|
6
|
+
let(:plex_delegate) {
|
7
|
+
section = plex_tv_section
|
8
|
+
show = section.all.first
|
9
|
+
season = show.seasons.first
|
10
|
+
season.episodes.first
|
11
|
+
}
|
13
12
|
|
14
13
|
describe "#initialize" do
|
15
14
|
|
@@ -19,7 +18,9 @@ describe TivoHMO::Adapters::Plex::Episode do
|
|
19
18
|
expect(episode).to be_a TivoHMO::API::Item
|
20
19
|
expect(episode.title).to eq(plex_delegate.title)
|
21
20
|
expect(episode.identifier).to eq(plex_delegate.key)
|
22
|
-
expect(episode.
|
21
|
+
expect(episode.file).to be_truthy
|
22
|
+
expect(episode.subtitle).to be_nil
|
23
|
+
expect(episode.modified_at).to eq(Time.at(plex_delegate.updated_at.to_i))
|
23
24
|
expect(episode.created_at).to eq(Time.parse(plex_delegate.originally_available_at))
|
24
25
|
end
|
25
26
|
|
@@ -32,13 +33,31 @@ describe TivoHMO::Adapters::Plex::Episode do
|
|
32
33
|
episode.app = TivoHMO::Adapters::Plex::Application.new('localhost')
|
33
34
|
md = episode.metadata
|
34
35
|
expect(md.original_air_date).to eq(Time.parse(plex_delegate.originally_available_at))
|
35
|
-
|
36
|
+
rating = plex_delegate.content_rating.upcase
|
37
|
+
expect(md.tv_rating).to eq({name: rating,
|
38
|
+
value: TivoHMO::API::Metadata::TV_RATINGS[rating]})
|
36
39
|
expect(md.is_episode).to eq(true)
|
37
|
-
|
38
|
-
expect(md.
|
39
|
-
expect(md.
|
40
|
-
expect(md.
|
41
|
-
expect(md.
|
40
|
+
epnum = "%i%02i" % [plex_delegate.parent_index, plex_delegate.index]
|
41
|
+
expect(md.episode_number).to eq(epnum)
|
42
|
+
expect(md.series_title).to eq(plex_delegate.grandparent_title)
|
43
|
+
expect(md.episode_title).to eq("#{epnum} - #{plex_delegate.title}")
|
44
|
+
expect(md.title).to eq("#{plex_delegate.grandparent_title} - #{plex_delegate.title}")
|
45
|
+
expect(md.series_id).to match(/SH[0-9]+/)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should allow disabling series id in metadata" do
|
49
|
+
described_class.config_set(:group_with_zap2it, true)
|
50
|
+
episode = described_class.new(plex_delegate)
|
51
|
+
episode.app = TivoHMO::Adapters::Plex::Application.new('localhost')
|
52
|
+
md = episode.metadata
|
53
|
+
normal_series_id = md.series_id
|
54
|
+
expect(normal_series_id).to match(/SH[0-9]+/)
|
55
|
+
|
56
|
+
described_class.config_set(:group_with_zap2it, false)
|
57
|
+
md = episode.metadata
|
58
|
+
zap2it_series_id = md.series_id
|
59
|
+
expect(zap2it_series_id).to match(/SH[0-9]+/)
|
60
|
+
expect(zap2it_series_id).to_not eq(normal_series_id)
|
42
61
|
end
|
43
62
|
|
44
63
|
end
|
@@ -1,12 +1,9 @@
|
|
1
1
|
require_relative "../../spec_helper"
|
2
2
|
require 'tivohmo/adapters/plex'
|
3
3
|
|
4
|
-
describe TivoHMO::Adapters::Plex::Metadata do
|
4
|
+
describe TivoHMO::Adapters::Plex::Metadata, :vcr do
|
5
5
|
|
6
|
-
let(:plex_delegate) {
|
7
|
-
summary: 'Summary',
|
8
|
-
duration: 10000,
|
9
|
-
rating: 10) }
|
6
|
+
let(:plex_delegate) { plex_movie_section.all.first }
|
10
7
|
|
11
8
|
let(:item) { double('item', delegate: plex_delegate)}
|
12
9
|
|
@@ -16,9 +13,10 @@ describe TivoHMO::Adapters::Plex::Metadata do
|
|
16
13
|
md = described_class.new(item)
|
17
14
|
expect(md).to be_a described_class
|
18
15
|
expect(md).to be_a TivoHMO::API::Metadata
|
19
|
-
expect(md.duration).to eq(plex_delegate.duration / 1000)
|
16
|
+
expect(md.duration).to eq(plex_delegate.duration.to_i / 1000)
|
20
17
|
expect(md.description).to eq plex_delegate.summary
|
21
|
-
expect(md.star_rating).to
|
18
|
+
expect(md.star_rating[:name]).to be_nonzero
|
19
|
+
expect(md.star_rating[:value]).to be_nonzero
|
22
20
|
end
|
23
21
|
|
24
22
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
require_relative "../../spec_helper"
|
2
2
|
require 'tivohmo/adapters/plex'
|
3
3
|
|
4
|
-
describe TivoHMO::Adapters::Plex::Movie do
|
4
|
+
describe TivoHMO::Adapters::Plex::Movie, :vcr do
|
5
5
|
|
6
|
-
let(:plex_delegate) {
|
7
|
-
originally_available_at: "2013-01-02",
|
8
|
-
content_rating: 'G') }
|
6
|
+
let(:plex_delegate) { plex_movie_section.all.first }
|
9
7
|
|
10
8
|
describe "#initialize" do
|
11
9
|
|
@@ -15,7 +13,9 @@ describe TivoHMO::Adapters::Plex::Movie do
|
|
15
13
|
expect(movie).to be_a TivoHMO::API::Item
|
16
14
|
expect(movie.title).to eq(plex_delegate.title)
|
17
15
|
expect(movie.identifier).to eq(plex_delegate.key)
|
18
|
-
expect(movie.
|
16
|
+
expect(movie.file).to be_truthy
|
17
|
+
expect(movie.subtitle).to be_nil
|
18
|
+
expect(movie.modified_at).to eq(Time.at(plex_delegate.updated_at.to_i))
|
19
19
|
expect(movie.created_at).to eq(Time.parse(plex_delegate.originally_available_at))
|
20
20
|
end
|
21
21
|
|
@@ -27,8 +27,11 @@ describe TivoHMO::Adapters::Plex::Movie do
|
|
27
27
|
movie = described_class.new(plex_delegate)
|
28
28
|
movie.app = TivoHMO::Adapters::Plex::Application.new('localhost')
|
29
29
|
md = movie.metadata
|
30
|
-
expect(md.movie_year).to eq(
|
31
|
-
|
30
|
+
expect(md.movie_year).to eq(plex_delegate.year.to_i)
|
31
|
+
rating = plex_delegate.content_rating.upcase
|
32
|
+
expect(md.mpaa_rating).to eq({name: rating,
|
33
|
+
value: TivoHMO::API::Metadata::MPAA_RATINGS[rating]})
|
34
|
+
|
32
35
|
end
|
33
36
|
|
34
37
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require_relative "../../spec_helper"
|
2
2
|
require 'tivohmo/adapters/plex'
|
3
3
|
|
4
|
-
describe TivoHMO::Adapters::Plex::QualifiedCategory do
|
4
|
+
describe TivoHMO::Adapters::Plex::QualifiedCategory, :vcr do
|
5
5
|
|
6
|
-
let(:plex_delegate) {
|
6
|
+
let(:plex_delegate) { plex_movie_section }
|
7
7
|
|
8
8
|
|
9
9
|
describe "#initialize" do
|
@@ -16,9 +16,10 @@ describe TivoHMO::Adapters::Plex::QualifiedCategory do
|
|
16
16
|
expect(qcat).to be_a TivoHMO::API::Container
|
17
17
|
expect(qcat.title).to eq("By Year")
|
18
18
|
expect(qcat.category_qualifier).to eq('2000')
|
19
|
+
expect(qcat.presorted).to eq(true)
|
19
20
|
expect(qcat.title).to eq("By Year")
|
20
21
|
expect(qcat.identifier).to eq(plex_delegate.key)
|
21
|
-
expect(qcat.modified_at).to eq(Time.at(plex_delegate.updated_at))
|
22
|
+
expect(qcat.modified_at).to eq(Time.at(plex_delegate.updated_at.to_i))
|
22
23
|
expect(qcat.created_at).to eq(now)
|
23
24
|
end
|
24
25
|
end
|
@@ -28,27 +29,26 @@ describe TivoHMO::Adapters::Plex::QualifiedCategory do
|
|
28
29
|
describe "#children" do
|
29
30
|
|
30
31
|
it "should memoize" do
|
31
|
-
listing = [
|
32
|
-
{title: 'Title1', key: 'key1'}
|
33
|
-
]
|
34
|
-
allow(plex_delegate).to receive(:years).and_return(listing)
|
35
32
|
section = described_class.new(plex_delegate, :by_year, :years)
|
36
33
|
expect(section.children.object_id).to eq(section.children.object_id)
|
37
34
|
end
|
38
35
|
|
39
36
|
it "should have children" do
|
40
|
-
listing = [
|
41
|
-
{title: 'Title1', key: 'key1'},
|
42
|
-
{title: 'Title2', key: 'key2'}
|
43
|
-
]
|
44
|
-
allow(plex_delegate).to receive(:years).and_return(listing)
|
45
37
|
section = described_class.new(plex_delegate, :by_year, :years)
|
46
|
-
expect(section.children
|
47
|
-
|
48
|
-
|
38
|
+
expect(section.children).to_not be_empty
|
39
|
+
section.children.all? {|c| expect(c).to be_instance_of(TivoHMO::Adapters::Plex::Category) }
|
40
|
+
section.children.all? {|c| expect(c.category_type).to be(:by_year) }
|
49
41
|
# reverse order due to sorting by title reversed to work with tivo newest first sorting
|
50
|
-
expect(section.children[
|
51
|
-
|
42
|
+
expect(section.children[1].category_value[:key]).to be > section.children[0].category_value[:key]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should display non-zero child_count once children fetched" do
|
46
|
+
section = described_class.new(plex_delegate, :by_year, :years)
|
47
|
+
|
48
|
+
expect(section.child_count).to be(0)
|
49
|
+
section.children
|
50
|
+
expect(section.child_count).to_not be(0)
|
51
|
+
expect(section.child_count).to eq(section.children.size)
|
52
52
|
end
|
53
53
|
|
54
54
|
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
require_relative "../../spec_helper"
|
2
2
|
require 'tivohmo/adapters/plex'
|
3
3
|
|
4
|
-
describe TivoHMO::Adapters::Plex::Season do
|
4
|
+
describe TivoHMO::Adapters::Plex::Season, :vcr do
|
5
5
|
|
6
|
-
let(:plex_delegate) {
|
6
|
+
let(:plex_delegate) {
|
7
|
+
section = plex_tv_section
|
8
|
+
show = section.all.first
|
9
|
+
show.seasons.first
|
10
|
+
}
|
7
11
|
|
8
12
|
describe "#initialize" do
|
9
13
|
|
@@ -13,10 +17,25 @@ describe TivoHMO::Adapters::Plex::Season do
|
|
13
17
|
expect(season).to be_a TivoHMO::API::Container
|
14
18
|
expect(season.title).to eq(plex_delegate.title)
|
15
19
|
expect(season.identifier).to eq(plex_delegate.key)
|
16
|
-
|
17
|
-
|
20
|
+
expect(season.modified_at).to eq(Time.at(plex_delegate.updated_at.to_i))
|
21
|
+
expect(season.created_at).to eq(Time.at(plex_delegate.added_at.to_i))
|
18
22
|
end
|
19
23
|
|
20
24
|
end
|
21
25
|
|
26
|
+
describe "#children" do
|
27
|
+
|
28
|
+
it "should memoize" do
|
29
|
+
season = described_class.new(plex_delegate)
|
30
|
+
expect(season.children.object_id).to eq(season.children.object_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have children" do
|
34
|
+
season = described_class.new(plex_delegate)
|
35
|
+
expect(season.children).to_not be_empty
|
36
|
+
season.children.all? {|c| expect(c).to be_instance_of(TivoHMO::Adapters::Plex::Episode) }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
22
41
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require_relative "../../spec_helper"
|
2
2
|
require 'tivohmo/adapters/plex'
|
3
3
|
|
4
|
-
describe TivoHMO::Adapters::Plex::Section do
|
4
|
+
describe TivoHMO::Adapters::Plex::Section, :vcr do
|
5
5
|
|
6
|
-
let(:plex_delegate) {
|
6
|
+
let(:plex_delegate) { plex_movie_section }
|
7
7
|
|
8
8
|
describe "#initialize" do
|
9
9
|
|
@@ -15,7 +15,7 @@ describe TivoHMO::Adapters::Plex::Section do
|
|
15
15
|
expect(section).to be_a TivoHMO::API::Container
|
16
16
|
expect(section.title).to eq(plex_delegate.title)
|
17
17
|
expect(section.identifier).to eq(plex_delegate.key)
|
18
|
-
expect(section.modified_at).to eq(Time.at(plex_delegate.updated_at))
|
18
|
+
expect(section.modified_at).to eq(Time.at(plex_delegate.updated_at.to_i))
|
19
19
|
expect(section.created_at).to eq(now)
|
20
20
|
end
|
21
21
|
end
|
@@ -31,7 +31,7 @@ describe TivoHMO::Adapters::Plex::Section do
|
|
31
31
|
|
32
32
|
it "should have category children" do
|
33
33
|
section = described_class.new(plex_delegate)
|
34
|
-
expect(section.children.size).
|
34
|
+
expect(section.children.size).to_not be(0)
|
35
35
|
classes = [TivoHMO::Adapters::Plex::Category, TivoHMO::Adapters::Plex::QualifiedCategory]
|
36
36
|
expect(section.children.collect(&:class).uniq.sort_by(&:name)).to eq(classes.sort_by(&:name))
|
37
37
|
end
|