tivohmo 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +7 -1
- data/CHANGELOG +10 -0
- data/README.md +5 -0
- data/TODO +3 -1
- data/contrib/tivohmo.yml +6 -0
- data/lib/tivohmo/adapters/plex.rb +6 -0
- data/lib/tivohmo/adapters/streamio/transcoder.rb +1 -1
- data/lib/tivohmo/cli.rb +10 -0
- data/lib/tivohmo/server.rb +29 -21
- data/lib/tivohmo/subtitles_util.rb +1 -1
- data/lib/tivohmo/version.rb +1 -1
- data/spec/cli_spec.rb +12 -1
- data/spec/server_spec.rb +19 -11
- data/spec/subtitles_util_spec.rb +2 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47cfc66b304a9e2077e46e6aa926b28f71d06b61
|
4
|
+
data.tar.gz: f3472e5e06a6167f772c4f6f6f2b78051673b4cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 526a4da9add7732b54b4579a692e1af98bd3fb7b9d8c8651ac12a461deb52def24a4a71ff2228ca3aab22cf76803b1b3584179f69affc62b0f68744425d581ce
|
7
|
+
data.tar.gz: b8fc08f4828cf93c6021a17b143328c6f5c9cff63199cf24367d0df0a71aa5073dd8bb50e56bfb06542631e99bc35ae3bc93e86934b2f26f540b2e78aa62016b
|
data/.travis.yml
CHANGED
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.3.2 (01/03/2016)
|
2
|
+
------------------
|
3
|
+
|
4
|
+
1.9.3 not supported <a2bd4bc> [Matt Conway]
|
5
|
+
TiVo Series 3 support: <486fa2e> [Scott Bailey]
|
6
|
+
add cli for setting arbitrary config <6171acb> [Matt Conway]
|
7
|
+
allow setting plex auth token <abc307a> [Matt Conway]
|
8
|
+
fix back after watching movie (anchor) <2737823> [Matt Conway]
|
9
|
+
use debug for transcode progress <4aae8d1> [Matt Conway]
|
10
|
+
|
1
11
|
0.3.1 (03/08/2015)
|
2
12
|
------------------
|
3
13
|
|
data/README.md
CHANGED
@@ -25,6 +25,11 @@ This project only supports serving of video resources (for now) as that fills my
|
|
25
25
|
|
26
26
|
## Installation
|
27
27
|
|
28
|
+
Install ffmpeg 2.x:
|
29
|
+
|
30
|
+
# On Mac OS X, use homebrew: http://brew.sh/
|
31
|
+
brew install ffmpeg
|
32
|
+
|
28
33
|
Install the gem:
|
29
34
|
|
30
35
|
$ gem install tivohmo
|
data/TODO
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
fix back after watching movie (anchor)
|
2
1
|
add audio track support similar to embedded subtitles
|
3
2
|
add embedded subtitles to filesystem app
|
4
3
|
figure out how to stream/transcode from plex rather than hack to use local files
|
5
4
|
figure out a way to embed subtitles in mpeg2 stream for live toggling from tivo ui (EIA-608/CEA-708/line 21)
|
5
|
+
Add push capability
|
6
|
+
Add html rendering of heirarchy for browsing/pushing
|
7
|
+
Add a plex plugin that allows one to trigger a push from plex ui (e.g. mobile plex client)
|
data/contrib/tivohmo.yml
CHANGED
@@ -35,6 +35,12 @@ applications:
|
|
35
35
|
# application: TivoHMO::Adapters::Filesystem::Application
|
36
36
|
# identifier: /My/Video
|
37
37
|
|
38
|
+
# Adapter specific configuration
|
39
|
+
# adapters:
|
40
|
+
# plex:
|
41
|
+
# # Optional, only needs to be set when plex user profiles have access control
|
42
|
+
# # https://support.plex.tv/hc/en-us/articles/204059436-Finding-your-account-token-X-Plex-Token
|
43
|
+
# auth_token: 'YOUR_TOKEN'
|
38
44
|
|
39
45
|
# BEGIN RUNTIME EDITABLE SETTINGS
|
40
46
|
#
|
@@ -1,4 +1,10 @@
|
|
1
1
|
require 'plex-ruby'
|
2
|
+
Plex.configure do |config|
|
3
|
+
# TODO: figure out a way to make this instance specific rather than global for all plex apps
|
4
|
+
token = TivoHMO::Config.instance.get(["adapters", "plex", "auth_token"])
|
5
|
+
config.auth_token = token if token.present?
|
6
|
+
end
|
7
|
+
|
2
8
|
require_relative 'plex/movie'
|
3
9
|
require_relative 'plex/episode'
|
4
10
|
require_relative 'plex/group'
|
@@ -248,7 +248,7 @@ module TivoHMO
|
|
248
248
|
begin
|
249
249
|
logger.info "Starting transcode of '#{movie.path}' to '#{output_filename}'"
|
250
250
|
transcoded_movie = movie.transcode(output_filename, opts, t_opts) do |progress|
|
251
|
-
logger.
|
251
|
+
logger.debug ("[%3i%%] Transcoding #{File.basename(movie.path)}" % (progress * 100).to_i)
|
252
252
|
raise "Halted" if Thread.current[:halt]
|
253
253
|
end
|
254
254
|
logger.info "Transcoding completed, transcoded file size: #{File.size(output_filename)}"
|
data/lib/tivohmo/cli.rb
CHANGED
@@ -70,6 +70,10 @@ module TivoHMO
|
|
70
70
|
option ["-f", "--configuration"],
|
71
71
|
"FILE", "load configuration from given filename\n"
|
72
72
|
|
73
|
+
option ["-c", "--configitem"],
|
74
|
+
"ITEM", "set configuration from given key=value item\n",
|
75
|
+
multivalued: true
|
76
|
+
|
73
77
|
option ["-s", "--settings"],
|
74
78
|
"FILE", "a writable file for storing runtime settings\n"
|
75
79
|
|
@@ -117,6 +121,12 @@ module TivoHMO
|
|
117
121
|
|
118
122
|
logger.info "TivoHMO #{TivoHMO::VERSION} starting up"
|
119
123
|
|
124
|
+
# set any config items passed in on cli
|
125
|
+
configitem_list.each do |item|
|
126
|
+
key, value = item.split('=')
|
127
|
+
Config.instance.set(key, value)
|
128
|
+
end
|
129
|
+
|
120
130
|
# allow cli option to override config file
|
121
131
|
set_if_default(:port, TivoHMO::Config.instance.get(:port).try(:to_i))
|
122
132
|
|
data/lib/tivohmo/server.rb
CHANGED
@@ -249,36 +249,41 @@ module TivoHMO
|
|
249
249
|
container = server.find(container_path)
|
250
250
|
halt 404, "No container found for #{container_path}" unless container
|
251
251
|
|
252
|
+
if anchor_item
|
253
|
+
anchor = server.find(anchor_item)
|
254
|
+
if anchor
|
255
|
+
container = anchor.parent
|
256
|
+
else
|
257
|
+
logger.warn "Anchor not found: #{anchor_item}"
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
252
261
|
children = container.children
|
253
262
|
|
254
263
|
children = select_all_items(children) if recurse
|
255
264
|
|
256
265
|
children = sort(children, sort_order) if sort_order && ! container.presorted
|
257
266
|
|
258
|
-
if
|
259
|
-
|
260
|
-
if
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
locals[:item_start] = item_start
|
269
|
-
else
|
270
|
-
logger.warn "Anchor not in container: #{container}, #{anchor_item}"
|
271
|
-
end
|
267
|
+
if anchor
|
268
|
+
idx = children.index(anchor)
|
269
|
+
if idx
|
270
|
+
# negative anchor means start N items before the anchor
|
271
|
+
# positive means start N items after the anchor
|
272
|
+
# ItemStart should be the index of the anchor with offset applied
|
273
|
+
anchor_offset = anchor_offset + 1 if anchor_offset < 0
|
274
|
+
item_start = idx + anchor_offset
|
275
|
+
item_start = 0 if item_start < 0
|
276
|
+
locals[:item_start] = item_start
|
272
277
|
else
|
273
|
-
logger.warn "Anchor not
|
274
|
-
end
|
275
|
-
else
|
276
|
-
if item_count < 0
|
277
|
-
locals[:item_start] = children.size + item_count
|
278
|
-
locals[:item_count] = - item_count
|
278
|
+
logger.warn "Anchor not in container: #{container}, #{anchor_item}"
|
279
279
|
end
|
280
280
|
end
|
281
281
|
|
282
|
+
if item_count < 0
|
283
|
+
locals[:item_start] = children.size + item_count
|
284
|
+
locals[:item_count] = - item_count
|
285
|
+
end
|
286
|
+
|
282
287
|
if container.root?
|
283
288
|
builder :server, layout: true,
|
284
289
|
locals: locals.merge(container: container, children: children)
|
@@ -313,7 +318,9 @@ module TivoHMO
|
|
313
318
|
builder :server_info, layout: true
|
314
319
|
|
315
320
|
when 'QueryItem' then
|
316
|
-
|
321
|
+
# pyTivo returns 404 when we try this (and doesn't crash the TiVo)
|
322
|
+
# builder(layout: true) {|xml| xml.QueryItem }
|
323
|
+
unsupported
|
317
324
|
|
318
325
|
when 'FlushServer' then
|
319
326
|
builder(layout: true) {|xml| xml.FlushServer }
|
@@ -337,6 +344,7 @@ module TivoHMO
|
|
337
344
|
response["Content-Type"] = format
|
338
345
|
|
339
346
|
stream do |out|
|
347
|
+
# Pulling h.264 ts fails if we include tivo_header, so it seems header is only needed for mpeg2 ts
|
340
348
|
out << tivo_header(item, format)
|
341
349
|
item.transcoder.transcode(out, format)
|
342
350
|
end
|
@@ -79,7 +79,7 @@ module TivoHMO
|
|
79
79
|
logger.debug "Setting up change listener on #{dir}"
|
80
80
|
|
81
81
|
listener = Listen.to(dir) do |modified, added, removed|
|
82
|
-
logger.debug "Detected filesystem change on #{dir}"
|
82
|
+
logger.debug "Detected filesystem change (#{added.size}/#{removed.size}) on #{dir}"
|
83
83
|
|
84
84
|
dirs = (added + removed).flatten.collect do |path|
|
85
85
|
logger.debug "Inspecting filesystem change: #{path}"
|
data/lib/tivohmo/version.rb
CHANGED
data/spec/cli_spec.rb
CHANGED
@@ -163,6 +163,17 @@ describe TivoHMO::CLI do
|
|
163
163
|
|
164
164
|
end
|
165
165
|
|
166
|
+
describe "--configitem" do
|
167
|
+
|
168
|
+
it "sets a config item" do
|
169
|
+
expect(TivoHMO::Server).to receive(:start)
|
170
|
+
cli.run(argv(minimal_args.merge(configitem: "adapters.plex.auth_token=abc123")))
|
171
|
+
expect(TivoHMO::Config.instance.get("adapters.plex.auth_token")).to eq('abc123')
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
|
166
177
|
describe "--port" do
|
167
178
|
|
168
179
|
it "has a default port" do
|
@@ -180,7 +191,7 @@ describe TivoHMO::CLI do
|
|
180
191
|
describe "--beacon" do
|
181
192
|
|
182
193
|
it "works with defaults" do
|
183
|
-
expect(TivoHMO::Beacon).to receive(:new).with(9032,
|
194
|
+
expect(TivoHMO::Beacon).to receive(:new).with(9032, {})
|
184
195
|
cli.run(argv(minimal_args))
|
185
196
|
end
|
186
197
|
|
data/spec/server_spec.rb
CHANGED
@@ -162,7 +162,8 @@ describe TivoHMO::Server do
|
|
162
162
|
|
163
163
|
it "should have a stub response for QueryItem" do
|
164
164
|
get '/TiVoConnect?Command=QueryItem'
|
165
|
-
|
165
|
+
# but make this 404 (like pyTivo) instead of 200
|
166
|
+
expect(last_response.status).to eq(404)
|
166
167
|
end
|
167
168
|
|
168
169
|
it "should have a response for QueryServer" do
|
@@ -516,17 +517,24 @@ describe TivoHMO::Server do
|
|
516
517
|
child_titles = doc.xpath("/TiVoContainer/Item/Details/Title").collect(&:content)
|
517
518
|
expect(child_titles).to match_array(["i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8"])
|
518
519
|
end
|
519
|
-
|
520
|
-
# [2014-12-07 21:23:00] INFO TivoHMO::Server Request from 192.168.1.12 "GET http:
|
521
|
-
# //192.168.1.188:9033/TiVoConnect?Command=QueryContainer&Container=%2FMatts%20Lap
|
522
|
-
# top%20(Plex)&Recurse=Yes&SortOrder=Title&ItemCount=8&AnchorItem=%2FMatts%20Lapto
|
523
|
-
# p%20(Plex)%2FAdult%20TV%20Shows%2FAll%2FMarvel's%20Agents%20of%20S.H.I.E.L.D.%2F
|
524
|
-
# Season%201%2FEye%20Spy&AnchorOffset=-5&Filter=x-tivo-container%2Ftivo-videos,x-t
|
525
|
-
# ivo-container%2Ffolder,video%2Fx-tivo-mpeg,video%2F*&SerialNum=848000190292CC9"
|
526
|
-
# [2014-12-07 21:23:00] DEBUG TivoHMO::Server Headers: {"Content-Type"=>nil}
|
527
|
-
# [2014-12-07 21:23:00] WARN TivoHMO::Server Anchor not in container: <TivoHMO::Adapters::Plex::Application: Plex[localhost:32400]>, /Matts Laptop (Plex)/Adult TV Shows/All/Marvel's Agents of S.H.I.E.L.D./Season 1/Eye Spy
|
528
|
-
# [2014-12-07 21:23:00] INFO TivoHMO::Server Response to 192.168.1.12 for "GET http://192.168.1.188:9033/TiVoConnect?Command=QueryContainer&Container=%2FMatts%20Laptop%20(Plex)&Recurse=Yes&SortOrder=Title&ItemCount=8&AnchorItem=%2FMatts%20Laptop%20(Plex)%2FAdult%20TV%20Shows%2FAll%2FMarvel's%20Agents%20of%20S.H.I.E.L.D.%2FSeason%201%2FEye%20Spy&AnchorOffset=-5&Filter=x-tivo-container%2Ftivo-videos,x-tivo-container%2Ffolder,video%2Fx-tivo-mpeg,video%2F*&SerialNum=848000190292CC9" [200]
|
529
520
|
|
521
|
+
it "overrides container with the one from anchor" do
|
522
|
+
get "/TiVoConnect?Command=QueryContainer&Container=/a1&AnchorItem=/a1/c1/i8&AnchorOffset=-1"
|
523
|
+
expect(last_response.status).to eq(200)
|
524
|
+
doc = Nokogiri::XML(last_response.body)
|
525
|
+
|
526
|
+
expect(doc.at_xpath("/TiVoContainer/Details/Title").content).to eq("/a1/c1")
|
527
|
+
|
528
|
+
expect(doc.at_xpath("/TiVoContainer/ItemStart").content).to eq("7")
|
529
|
+
expect(doc.at_xpath("/TiVoContainer/ItemCount").content).to eq("8")
|
530
|
+
|
531
|
+
expect(doc.at_xpath("/TiVoContainer/Details/TotalItems").content).to eq("20")
|
532
|
+
|
533
|
+
expect(doc.xpath("/TiVoContainer/Item").size).to eq (8)
|
534
|
+
|
535
|
+
child_titles = doc.xpath("/TiVoContainer/Item/Details/Title").collect(&:content)
|
536
|
+
expect(child_titles).to match_array(["i8", "i9", "i10", "i11", "i12", "i13", "i14", "i15"])
|
537
|
+
end
|
530
538
|
|
531
539
|
end
|
532
540
|
|
data/spec/subtitles_util_spec.rb
CHANGED
@@ -41,6 +41,7 @@ describe TivoHMO::SubtitlesUtil do
|
|
41
41
|
subs = subject.subtitles_for_media_file("#{dir}/1.avi")
|
42
42
|
expect(subs.size).to eq(0)
|
43
43
|
|
44
|
+
sleep 0.1
|
44
45
|
FileUtils.touch("#{dir}/1.en.srt")
|
45
46
|
sleep 0.5
|
46
47
|
|
@@ -55,6 +56,7 @@ describe TivoHMO::SubtitlesUtil do
|
|
55
56
|
subs = subject.subtitles_for_media_file("#{dir}/1.avi")
|
56
57
|
expect(subs.size).to eq(1)
|
57
58
|
|
59
|
+
sleep 0.1
|
58
60
|
FileUtils.rm("#{dir}/1.en.srt")
|
59
61
|
sleep 0.5
|
60
62
|
|
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.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Conway
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -525,7 +525,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
525
525
|
version: '0'
|
526
526
|
requirements: []
|
527
527
|
rubyforge_project:
|
528
|
-
rubygems_version: 2.
|
528
|
+
rubygems_version: 2.5.1
|
529
529
|
signing_key:
|
530
530
|
specification_version: 4
|
531
531
|
summary: Ruby SDK for Tivo Home Media Option
|