tivohmo 0.1.4 → 0.2.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG +11 -0
- data/contrib/tivohmo.plist +7 -3
- data/lib/tivohmo/adapters/plex/episode.rb +26 -0
- data/lib/tivohmo/adapters/plex/metadata.rb +7 -0
- data/lib/tivohmo/adapters/plex/movie.rb +13 -0
- data/lib/tivohmo/adapters/plex/transcoder.rb +1 -1
- data/lib/tivohmo/adapters/streamio/transcoder.rb +33 -17
- data/lib/tivohmo/api/metadata.rb +15 -0
- data/lib/tivohmo/cli.rb +21 -1
- data/lib/tivohmo/server.rb +7 -0
- data/lib/tivohmo/version.rb +1 -1
- data/spec/adapters/plex/episode_spec.rb +25 -1
- data/spec/adapters/plex/metadata_spec.rb +3 -1
- data/spec/adapters/plex/movie_spec.rb +15 -1
- data/spec/adapters/plex/transcoder_spec.rb +2 -2
- data/spec/cli_spec.rb +10 -0
- data/spec/server_spec.rb +16 -0
- data/spec/spec_helper.rb +3 -0
- data/tivohmo.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6513addd49cd73d0c775c59dc61f1b50c1efb335
|
4
|
+
data.tar.gz: f1e455479caff464c3bfd800ca7debd5aa2ed57c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c53ffcccd988944ebb7e95ce86a722052ec42198ca1b01d41e26ce71f5e0230652b7585244414b8ab8f9575a1fd5d0dc3e25f8fde1466ec12cb6af27f3f8627
|
7
|
+
data.tar.gz: c00d7b88d4551f34fcace28ebd0bd9b714dc8f21926ce3581e918965a77a87d67f5a61f4e1d8bde6e045117bba0044500be3736b58490d56a7f98353f23c3cb1
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
0.2.0 (11/23/2014)
|
2
|
+
------------------
|
3
|
+
|
4
|
+
add more metadata from plex <d048373> [Matt Conway]
|
5
|
+
add version as option and to normal startup messaging Capture stdout/err to logfile when provided <dd4bae7> [Matt Conway]
|
6
|
+
force encoding for detail xml in tivo_header handle negative ItemCount for tivo jump to end of list command <8229e22> [Matt Conway]
|
7
|
+
more function launchagent script <51e62de> [Matt Conway]
|
8
|
+
refactor plex metadata <76825e7> [Matt Conway]
|
9
|
+
unescape filename from plex <0502964> [Matt Conway]
|
10
|
+
use forked streamio-ffmpeg (due to lack of maintenance) to allow use with ffmpeg 2.4.x <c7e16e1> [Matt Conway]
|
11
|
+
|
1
12
|
0.1.4 (10/12/2014)
|
2
13
|
------------------
|
3
14
|
|
data/contrib/tivohmo.plist
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
<!--
|
4
4
|
Launchd (OS X) configuration for TivoHMO
|
5
5
|
Copy to ~/Library/LaunchAgents and edit as desired
|
6
|
-
Then to start the server, run:
|
6
|
+
Then to start the server, run: launchctl load ~/Library/LaunchAgents/tivohmo.plist
|
7
7
|
-->
|
8
8
|
|
9
9
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
@@ -13,10 +13,14 @@ Then to start the server, run: launchd load ~/Library/LaunchAgents/tivohmo.plist
|
|
13
13
|
<string>TivoHMO</string>
|
14
14
|
<key>ProgramArguments</key>
|
15
15
|
<array>
|
16
|
-
<string>
|
17
|
-
<string
|
16
|
+
<string>bash</string>
|
17
|
+
<string>-l</string>
|
18
|
+
<string>-c</string>
|
19
|
+
<string>tivohmo -p 9033 -l ~/Library/Logs/tivohmo.log -a TivoHMO::Adapters::Plex::Application -i localhost -t 'Plex Videos'</string>
|
18
20
|
</array>
|
19
21
|
<key>RunAtLoad</key>
|
20
22
|
<true/>
|
23
|
+
<key>KeepAlive</key>
|
24
|
+
<true/>
|
21
25
|
</dict>
|
22
26
|
</plist>
|
@@ -19,6 +19,32 @@ module TivoHMO
|
|
19
19
|
self.created_at = Time.at(delegate.added_at.to_i)
|
20
20
|
end
|
21
21
|
|
22
|
+
def metadata
|
23
|
+
md = super
|
24
|
+
|
25
|
+
md.original_air_date = Time.parse(delegate.originally_available_at) rescue nil
|
26
|
+
|
27
|
+
rating_name = delegate.content_rating.upcase
|
28
|
+
rating_value = TivoHMO::API::Metadata::TV_RATINGS[rating_name]
|
29
|
+
if rating_value
|
30
|
+
md.tv_rating = {name: rating_name, value: rating_value}
|
31
|
+
end
|
32
|
+
|
33
|
+
md.is_episode = true
|
34
|
+
md.episode_number = "%i%02i" % [delegate.parent_index, delegate.index]
|
35
|
+
md.series_title = delegate.grandparent_title
|
36
|
+
md.episode_title = "%i - %s" % [md.episode_number, title]
|
37
|
+
md.title = "%s - %s" % [delegate.grandparent_title, title]
|
38
|
+
|
39
|
+
# group tv shows under same name if we can extract a seriesId
|
40
|
+
guid = delegate.guid
|
41
|
+
if guid =~ /thetvdb:\/\/(\d+)/
|
42
|
+
md.series_id = "SH#{$1}"
|
43
|
+
end
|
44
|
+
|
45
|
+
md
|
46
|
+
end
|
47
|
+
|
22
48
|
end
|
23
49
|
|
24
50
|
end
|
@@ -12,6 +12,13 @@ module TivoHMO
|
|
12
12
|
begin
|
13
13
|
self.description = item.delegate.summary
|
14
14
|
self.duration = (item.delegate.duration.to_i / 1000).to_i
|
15
|
+
|
16
|
+
# plex 0-10 => tivo 1-7 for value, 0-4 in .5 increments for name
|
17
|
+
plex_rating = item.delegate.rating.to_f
|
18
|
+
rating_value = (plex_rating / 10 * 6).round
|
19
|
+
rating_name = [1, 1.5, 2, 2.5, 3, 3.5, 4][rating_value]
|
20
|
+
self.star_rating = {name: rating_name, value: rating_value + 1}
|
21
|
+
|
15
22
|
rescue => e
|
16
23
|
logger.error "Failed to read plex metadata: #{e}"
|
17
24
|
end
|
@@ -19,6 +19,19 @@ module TivoHMO
|
|
19
19
|
self.created_at = Time.at(delegate.added_at.to_i)
|
20
20
|
end
|
21
21
|
|
22
|
+
def metadata
|
23
|
+
md = super
|
24
|
+
md.movie_year = Time.parse(delegate.originally_available_at).year rescue nil
|
25
|
+
|
26
|
+
rating_name = delegate.content_rating.upcase
|
27
|
+
rating_value = TivoHMO::API::Metadata::MPAA_RATINGS[rating_name]
|
28
|
+
if rating_value
|
29
|
+
md.mpaa_rating = {name: rating_name, value: rating_value}
|
30
|
+
end
|
31
|
+
|
32
|
+
md
|
33
|
+
end
|
34
|
+
|
22
35
|
end
|
23
36
|
|
24
37
|
end
|
@@ -35,9 +35,9 @@ module TivoHMO
|
|
35
35
|
|
36
36
|
def transcoder_options(format="video/x-tivo-mpeg")
|
37
37
|
opts = {
|
38
|
-
video_max_bitrate:
|
38
|
+
video_max_bitrate: 30_000_000,
|
39
39
|
buffer_size: 4096,
|
40
|
-
audio_bitrate:
|
40
|
+
audio_bitrate: 448_000,
|
41
41
|
format: format,
|
42
42
|
custom: []
|
43
43
|
}
|
@@ -47,6 +47,7 @@ module TivoHMO
|
|
47
47
|
opts = select_video_codec(opts)
|
48
48
|
opts = select_video_bitrate(opts)
|
49
49
|
opts = select_audio_codec(opts)
|
50
|
+
opts = select_audio_bitrate(opts)
|
50
51
|
opts = select_audio_sample_rate(opts)
|
51
52
|
opts = select_container(opts)
|
52
53
|
|
@@ -96,6 +97,13 @@ module TivoHMO
|
|
96
97
|
opts
|
97
98
|
end
|
98
99
|
|
100
|
+
def select_audio_bitrate(opts)
|
101
|
+
# transcode assumes unit of Kbit, whilst video_info has unit of bit
|
102
|
+
opts[:audio_bitrate] = (opts[:audio_bitrate] / 1000).to_i
|
103
|
+
|
104
|
+
opts
|
105
|
+
end
|
106
|
+
|
99
107
|
def select_audio_codec(opts)
|
100
108
|
if video_info[:audio_codec]
|
101
109
|
if AUDIO_CODECS.any? { |ac| video_info[:audio_codec] =~ /#{ac}/ }
|
@@ -111,18 +119,24 @@ module TivoHMO
|
|
111
119
|
end
|
112
120
|
|
113
121
|
def select_video_bitrate(opts)
|
114
|
-
|
115
122
|
vbr = video_info[:video_bitrate]
|
123
|
+
default_vbr = 16_384_000
|
116
124
|
|
117
125
|
if vbr && vbr > 0
|
118
126
|
if vbr >= opts[:video_max_bitrate]
|
119
|
-
opts[:video_bitrate] = (
|
120
|
-
|
127
|
+
opts[:video_bitrate] = (opts[:video_max_bitrate] * 0.95).to_i
|
128
|
+
elsif vbr > default_vbr
|
121
129
|
opts[:video_bitrate] = vbr
|
130
|
+
else
|
131
|
+
opts[:video_bitrate] = default_vbr
|
122
132
|
end
|
123
133
|
end
|
124
134
|
|
125
|
-
opts[:video_bitrate] ||=
|
135
|
+
opts[:video_bitrate] ||= default_vbr
|
136
|
+
|
137
|
+
# transcode assumes unit of Kbit, whilst video_info has unit of bit
|
138
|
+
opts[:video_bitrate] = (opts[:video_bitrate] / 1000).to_i
|
139
|
+
opts[:video_max_bitrate] = (opts[:video_max_bitrate] / 1000).to_i
|
126
140
|
|
127
141
|
opts
|
128
142
|
end
|
@@ -141,7 +155,6 @@ module TivoHMO
|
|
141
155
|
end
|
142
156
|
|
143
157
|
def select_video_dimensions(opts)
|
144
|
-
preserve_aspect = nil
|
145
158
|
video_width = video_info[:width].to_i
|
146
159
|
VIDEO_WIDTHS.each do |w|
|
147
160
|
w = w.to_i
|
@@ -163,34 +176,37 @@ module TivoHMO
|
|
163
176
|
end
|
164
177
|
end
|
165
178
|
video_height = VIDEO_HEIGHTS.last.to_i unless video_height
|
179
|
+
|
166
180
|
opts[:resolution] = "#{video_width}x#{video_height}"
|
167
|
-
opts[:preserve_aspect_ratio]
|
181
|
+
opts[:preserve_aspect_ratio] ||= :height
|
168
182
|
opts
|
169
183
|
end
|
170
184
|
|
171
185
|
def select_video_frame_rate(opts)
|
172
186
|
|
173
|
-
frame_rate = video_info[:frame_rate]
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
end
|
187
|
+
frame_rate = video_info[:frame_rate]
|
188
|
+
if frame_rate =~ /\A[0-9\.]+\Z/
|
189
|
+
frame_rate = frame_rate.to_f
|
190
|
+
elsif frame_rate =~ /\A\((\d+)\/(\d+)\)\Z/
|
191
|
+
frame_rate = $1.to_f / $2.to_f
|
179
192
|
end
|
180
193
|
|
181
|
-
|
194
|
+
VIDEO_FRAME_RATES.each do |r|
|
195
|
+
opts[:frame_rate] = r
|
196
|
+
break if frame_rate >= r.to_f
|
197
|
+
end
|
182
198
|
|
183
199
|
opts
|
184
200
|
end
|
185
201
|
|
186
202
|
def run_transcode(output_filename, format)
|
187
203
|
|
188
|
-
logger.
|
204
|
+
logger.info "Movie Info: " +
|
189
205
|
video_info.collect {|k, v| "#{k}=#{v.inspect}"}.join(' ')
|
190
206
|
|
191
207
|
opts = transcoder_options(format)
|
192
208
|
|
193
|
-
logger.
|
209
|
+
logger.info "Transcoding options: " +
|
194
210
|
opts.collect {|k, v| "#{k}='#{v}'"}.join(' ')
|
195
211
|
|
196
212
|
|
data/lib/tivohmo/api/metadata.rb
CHANGED
@@ -6,6 +6,21 @@ module TivoHMO
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
include GemLogger::LoggerSupport
|
8
8
|
|
9
|
+
MPAA_RATINGS = {
|
10
|
+
'G' => 1, 'PG' => 2, 'PG-13' => 3, 'PG13' => 3, 'R' => 4, 'X' => 5,
|
11
|
+
'NC-17' => 6, 'NC17' => 6, 'NR' => 8, 'UNRATED' => 8, 'G1' => 1,
|
12
|
+
'P2' => 2, 'P3' => 3, 'R4' => 4, 'X5' => 5, 'N6' => 6, 'N8' => 8
|
13
|
+
}
|
14
|
+
|
15
|
+
TV_RATINGS = {
|
16
|
+
'TV-Y7' => 1, 'TV-Y' => 2, 'TV-G' => 3, 'TV-PG' => 4, 'TV-14' => 5,
|
17
|
+
'TV-MA' => 6, 'TV-NR' => 7, 'TVY7' => 1, 'TVY' => 2, 'TVG' => 3,
|
18
|
+
'TVPG' => 4, 'TV14' => 5, 'TVMA' => 6, 'TVNR' => 7, 'Y7' => 1,
|
19
|
+
'Y' => 2, 'G' => 3, 'PG' => 4, '14' => 5, 'MA' => 6, 'NR' => 7,
|
20
|
+
'UNRATED' => 7, 'X1' => 1, 'X2' => 2, 'X3' => 3, 'X4' => 4, 'X5' => 5,
|
21
|
+
'X6' => 6, 'X7' => 7
|
22
|
+
}
|
23
|
+
|
9
24
|
attr_accessor :item,
|
10
25
|
|
11
26
|
:title,
|
data/lib/tivohmo/cli.rb
CHANGED
@@ -42,6 +42,10 @@ module TivoHMO
|
|
42
42
|
:flag, "debug output\n",
|
43
43
|
default: false
|
44
44
|
|
45
|
+
option ["-v", "--version"],
|
46
|
+
:flag, "print version and exit\n",
|
47
|
+
default: false
|
48
|
+
|
45
49
|
option ["-r", "--preload"],
|
46
50
|
:flag, "Preloads all lazy container listings\n",
|
47
51
|
default: false
|
@@ -83,8 +87,15 @@ module TivoHMO
|
|
83
87
|
"LIMIT:INTERVAL", "configure beacon limit and/or interval\n"
|
84
88
|
|
85
89
|
def execute
|
90
|
+
if version?
|
91
|
+
puts "TivoHMO Version #{TivoHMO::VERSION}"
|
92
|
+
return
|
93
|
+
end
|
94
|
+
|
86
95
|
setup_logging
|
87
96
|
|
97
|
+
logger.info "TivoHMO #{TivoHMO::VERSION} starting up"
|
98
|
+
|
88
99
|
if configuration
|
89
100
|
config = YAML.load_file(configuration)
|
90
101
|
|
@@ -146,12 +157,21 @@ module TivoHMO
|
|
146
157
|
Logging.logger.root.level = :debug if debug?
|
147
158
|
|
148
159
|
if logfile.present?
|
149
|
-
|
160
|
+
appender = Logging.appenders.rolling_file(
|
150
161
|
logfile,
|
162
|
+
truncate: true,
|
163
|
+
age: 'daily',
|
164
|
+
keep: 3,
|
151
165
|
layout: Logging.layouts.pattern(
|
152
166
|
pattern: Logging.appenders.stdout.layout.pattern
|
153
167
|
)
|
154
168
|
)
|
169
|
+
|
170
|
+
# hack to assign stdout/err to logfile if logging to file
|
171
|
+
io = appender.instance_variable_get(:@io)
|
172
|
+
$stdout = $stderr = io
|
173
|
+
|
174
|
+
Logging.logger.root.appenders = appender
|
155
175
|
end
|
156
176
|
end
|
157
177
|
|
data/lib/tivohmo/server.rb
CHANGED
@@ -147,6 +147,8 @@ module TivoHMO
|
|
147
147
|
end
|
148
148
|
|
149
149
|
item_details_xml = builder :item_details, layout: true, locals: {item: item}
|
150
|
+
item_details_xml.force_encoding('ascii-8bit')
|
151
|
+
|
150
152
|
ld = item_details_xml.bytesize
|
151
153
|
chunk = item_details_xml + '\0' * (pad(ld, 4) + 4)
|
152
154
|
lc = chunk.bytesize
|
@@ -233,6 +235,11 @@ module TivoHMO
|
|
233
235
|
else
|
234
236
|
logger.warn "Anchor not found: #{anchor_item}"
|
235
237
|
end
|
238
|
+
else
|
239
|
+
if item_count < 0
|
240
|
+
locals[:item_start] = children.size + item_count
|
241
|
+
locals[:item_count] = - item_count
|
242
|
+
end
|
236
243
|
end
|
237
244
|
|
238
245
|
if container.root?
|
data/lib/tivohmo/version.rb
CHANGED
@@ -3,7 +3,13 @@ require 'tivohmo/adapters/plex'
|
|
3
3
|
|
4
4
|
describe TivoHMO::Adapters::Plex::Episode do
|
5
5
|
|
6
|
-
let(:plex_delegate) { plex_stub(::Plex::Episode
|
6
|
+
let(:plex_delegate) { plex_stub(::Plex::Episode,
|
7
|
+
content_rating: 'G',
|
8
|
+
index: 2,
|
9
|
+
parent_index: 1,
|
10
|
+
grandparent_title: 'ShowTitle',
|
11
|
+
guid: "com.plexapp.agents.thetvdb://269650/1/2?lang=en",
|
12
|
+
originally_available_at: "2014-06-04") }
|
7
13
|
|
8
14
|
describe "#initialize" do
|
9
15
|
|
@@ -19,4 +25,22 @@ describe TivoHMO::Adapters::Plex::Episode do
|
|
19
25
|
|
20
26
|
end
|
21
27
|
|
28
|
+
describe "#metadata" do
|
29
|
+
|
30
|
+
it "should populate metadata" do
|
31
|
+
episode = described_class.new(plex_delegate)
|
32
|
+
episode.app = TivoHMO::Adapters::Plex::Application.new('localhost')
|
33
|
+
md = episode.metadata
|
34
|
+
expect(md.original_air_date).to eq(Time.parse(plex_delegate.originally_available_at))
|
35
|
+
expect(md.tv_rating).to eq({name: 'G', value: 3})
|
36
|
+
expect(md.is_episode).to eq(true)
|
37
|
+
expect(md.episode_number).to eq("102")
|
38
|
+
expect(md.series_title).to eq("ShowTitle")
|
39
|
+
expect(md.episode_title).to eq("102 - Title")
|
40
|
+
expect(md.title).to eq("ShowTitle - Title")
|
41
|
+
expect(md.series_id).to eq("SH269650")
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
22
46
|
end
|
@@ -5,7 +5,8 @@ describe TivoHMO::Adapters::Plex::Metadata do
|
|
5
5
|
|
6
6
|
let(:plex_delegate) { plex_stub(::Plex::Movie,
|
7
7
|
summary: 'Summary',
|
8
|
-
duration: 10000
|
8
|
+
duration: 10000,
|
9
|
+
rating: 10) }
|
9
10
|
|
10
11
|
let(:item) { double('item', delegate: plex_delegate)}
|
11
12
|
|
@@ -17,6 +18,7 @@ describe TivoHMO::Adapters::Plex::Metadata do
|
|
17
18
|
expect(md).to be_a TivoHMO::API::Metadata
|
18
19
|
expect(md.duration).to eq(plex_delegate.duration / 1000)
|
19
20
|
expect(md.description).to eq plex_delegate.summary
|
21
|
+
expect(md.star_rating).to eq({name: 4, value: 7})
|
20
22
|
end
|
21
23
|
|
22
24
|
end
|
@@ -3,7 +3,9 @@ require 'tivohmo/adapters/plex'
|
|
3
3
|
|
4
4
|
describe TivoHMO::Adapters::Plex::Movie do
|
5
5
|
|
6
|
-
let(:plex_delegate) { plex_stub(::Plex::Movie
|
6
|
+
let(:plex_delegate) { plex_stub(::Plex::Movie,
|
7
|
+
originally_available_at: "2013-01-02",
|
8
|
+
content_rating: 'G') }
|
7
9
|
|
8
10
|
describe "#initialize" do
|
9
11
|
|
@@ -19,4 +21,16 @@ describe TivoHMO::Adapters::Plex::Movie do
|
|
19
21
|
|
20
22
|
end
|
21
23
|
|
24
|
+
describe "#metadata" do
|
25
|
+
|
26
|
+
it "should populate metadata" do
|
27
|
+
movie = described_class.new(plex_delegate)
|
28
|
+
movie.app = TivoHMO::Adapters::Plex::Application.new('localhost')
|
29
|
+
md = movie.metadata
|
30
|
+
expect(md.movie_year).to eq(2013)
|
31
|
+
expect(md.mpaa_rating).to eq({name: 'G', value: 1})
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
22
36
|
end
|
@@ -9,7 +9,7 @@ describe TivoHMO::Adapters::Plex::Transcoder do
|
|
9
9
|
duration: 10000,
|
10
10
|
medias: [double('media',
|
11
11
|
parts: [double('part',
|
12
|
-
file: '/foo')])])}
|
12
|
+
file: '/foo%20bar')])])}
|
13
13
|
|
14
14
|
let(:item) { double('item', identifier: plex_delegate.key, delegate: plex_delegate)}
|
15
15
|
|
@@ -19,7 +19,7 @@ describe TivoHMO::Adapters::Plex::Transcoder do
|
|
19
19
|
trans = described_class.new(item)
|
20
20
|
expect(trans).to be_a described_class
|
21
21
|
expect(trans).to be_a TivoHMO::API::Transcoder
|
22
|
-
expect(trans.source_filename).to eq '/foo'
|
22
|
+
expect(trans.source_filename).to eq '/foo bar'
|
23
23
|
end
|
24
24
|
|
25
25
|
end
|
data/spec/cli_spec.rb
CHANGED
@@ -39,6 +39,16 @@ describe TivoHMO::CLI do
|
|
39
39
|
|
40
40
|
end
|
41
41
|
|
42
|
+
describe "--version" do
|
43
|
+
|
44
|
+
it "produces version text under standard width" do
|
45
|
+
expect(cli).to receive(:setup_logging).never
|
46
|
+
expect($stdout).to receive(:puts).with(/#{TivoHMO::VERSION}/)
|
47
|
+
cli.run(["--version"])
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
42
52
|
describe "--debug" do
|
43
53
|
|
44
54
|
it "defaults to info log level" do
|
data/spec/server_spec.rb
CHANGED
@@ -385,6 +385,22 @@ describe TivoHMO::Server do
|
|
385
385
|
expect(child_titles).to match_array(["i1", "i2", "i3"])
|
386
386
|
end
|
387
387
|
|
388
|
+
it "honors negative ItemCount (jump to last page)" do
|
389
|
+
get "/TiVoConnect?Command=QueryContainer&Container=/a1/c1&ItemCount=-3"
|
390
|
+
expect(last_response.status).to eq(200)
|
391
|
+
doc = Nokogiri::XML(last_response.body)
|
392
|
+
|
393
|
+
expect(doc.at_xpath("/TiVoContainer/ItemStart").content).to eq("17")
|
394
|
+
expect(doc.at_xpath("/TiVoContainer/ItemCount").content).to eq("3")
|
395
|
+
|
396
|
+
expect(doc.at_xpath("/TiVoContainer/Details/TotalItems").content).to eq("20")
|
397
|
+
|
398
|
+
expect(doc.xpath("/TiVoContainer/Item").size).to eq (3)
|
399
|
+
|
400
|
+
child_titles = doc.xpath("/TiVoContainer/Item/Details/Title").collect(&:content)
|
401
|
+
expect(child_titles).to match_array(["i18", "i19", "i20"])
|
402
|
+
end
|
403
|
+
|
388
404
|
it "displays page 2" do
|
389
405
|
get "/TiVoConnect?Command=QueryContainer&Container=/a1/c1&ItemStart=7"
|
390
406
|
expect(last_response.status).to eq(200)
|
data/spec/spec_helper.rb
CHANGED
data/tivohmo.gemspec
CHANGED
@@ -39,7 +39,7 @@ Gem::Specification.new do |spec|
|
|
39
39
|
|
40
40
|
# filesystem adapter dependencies, make optional?
|
41
41
|
spec.add_dependency "listen"
|
42
|
-
spec.add_dependency "streamio-ffmpeg"
|
42
|
+
spec.add_dependency "tivohmo-streamio-ffmpeg"
|
43
43
|
|
44
44
|
# plex adapter dependencies, make optional?
|
45
45
|
spec.add_dependency "plex-ruby"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tivohmo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Conway
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -249,7 +249,7 @@ dependencies:
|
|
249
249
|
- !ruby/object:Gem::Version
|
250
250
|
version: '0'
|
251
251
|
- !ruby/object:Gem::Dependency
|
252
|
-
name: streamio-ffmpeg
|
252
|
+
name: tivohmo-streamio-ffmpeg
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|
254
254
|
requirements:
|
255
255
|
- - ">="
|
@@ -415,3 +415,4 @@ test_files:
|
|
415
415
|
- spec/cli_spec.rb
|
416
416
|
- spec/server_spec.rb
|
417
417
|
- spec/spec_helper.rb
|
418
|
+
has_rdoc:
|