plex-ruby 0.2.0 → 0.3.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.
- data/CHANGELOG.md +5 -0
- data/README.md +1 -1
- data/lib/plex-ruby.rb +1 -13
- data/lib/plex-ruby/client.rb +12 -4
- data/lib/plex-ruby/episode.rb +10 -3
- data/lib/plex-ruby/library.rb +13 -2
- data/lib/plex-ruby/media.rb +2 -0
- data/lib/plex-ruby/movie.rb +10 -3
- data/lib/plex-ruby/parser.rb +10 -7
- data/lib/plex-ruby/part.rb +2 -0
- data/lib/plex-ruby/season.rb +12 -5
- data/lib/plex-ruby/section.rb +22 -14
- data/lib/plex-ruby/server.rb +7 -4
- data/lib/plex-ruby/show.rb +12 -5
- data/lib/plex-ruby/stream.rb +2 -0
- data/lib/plex-ruby/version.rb +1 -1
- data/lib/plex-ruby/video.rb +2 -0
- metadata +1 -1
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -54,7 +54,7 @@ puts "#{episodes.first.title} - #{episodes.first.summary}" # Looks good
|
|
54
54
|
client.play_media(episodes.first.key) # Play it!
|
55
55
|
```
|
56
56
|
|
57
|
-
For a full list of commands check out the documentation.
|
57
|
+
For a full list of commands check out the [documentation](http://rubydoc.info/github/ekosz/Plex-Ruby/master/frames).
|
58
58
|
|
59
59
|
## Development
|
60
60
|
|
data/lib/plex-ruby.rb
CHANGED
@@ -5,7 +5,7 @@ require 'cgi'
|
|
5
5
|
module Plex
|
6
6
|
|
7
7
|
# Converts camel case names that are commonly found in the Plex APIs into
|
8
|
-
# ruby friendly names. I.E. playMedia -> play_media
|
8
|
+
# ruby friendly names. I.E. <tt>playMedia</tt> -> <tt>play_media</tt>
|
9
9
|
#
|
10
10
|
# @param [String] camel case name to be converted
|
11
11
|
# @return [String] snake case form
|
@@ -17,18 +17,6 @@ module Plex
|
|
17
17
|
downcase
|
18
18
|
end
|
19
19
|
|
20
|
-
# The base url of the Plex Media Server, I.E. 'http://localhost:32400'
|
21
|
-
# !WARNING! This method will most likely be replaced in future versions
|
22
|
-
#
|
23
|
-
# @return [String] bases url of the Plex Media Server
|
24
|
-
def self.url
|
25
|
-
@@base_url
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.url=(val)
|
29
|
-
@@base_url = val
|
30
|
-
end
|
31
|
-
|
32
20
|
end
|
33
21
|
|
34
22
|
require 'plex-ruby/parser'
|
data/lib/plex-ruby/client.rb
CHANGED
@@ -7,9 +7,13 @@ module Plex
|
|
7
7
|
PLAYBACK_METHODS = %w(play pause stop rewind fastForward stepForward
|
8
8
|
bigStepForward stepBack bigStepBack skipNext skipPrevious)
|
9
9
|
|
10
|
-
attr_reader :name, :host, :address, :port, :machine_identifier, :version
|
10
|
+
attr_reader :server, :name, :host, :address, :port, :machine_identifier, :version
|
11
11
|
|
12
|
-
|
12
|
+
|
13
|
+
# @param [Server] server this client belongs to
|
14
|
+
# @param [Nokogiri::XML::Element] nokogiri element to build from
|
15
|
+
def initialize(server, node)
|
16
|
+
@server = server
|
13
17
|
@name = node.attr('name')
|
14
18
|
@host = node.attr('host')
|
15
19
|
@address = node.attr('address')
|
@@ -59,7 +63,7 @@ module Plex
|
|
59
63
|
# the console for the error message
|
60
64
|
def play_media(key, user_agent = nil, http_cookies = nil, view_offset = nil)
|
61
65
|
url = player_url+'/application/playMedia?'
|
62
|
-
url += "path=#{CGI::escape(
|
66
|
+
url += "path=#{CGI::escape(server.url+key)}"
|
63
67
|
url += "&key=#{CGI::escape(key)}"
|
64
68
|
url += "&userAgent=#{user_agent}" if user_agent
|
65
69
|
url += "&httpCookies=#{http_cookies}" if http_cookies
|
@@ -111,10 +115,14 @@ module Plex
|
|
111
115
|
ping player_url+"/application/sendVirtualKey?code=#{CGI::escape(code.to_s)}"
|
112
116
|
end
|
113
117
|
|
118
|
+
def url
|
119
|
+
server.url
|
120
|
+
end
|
121
|
+
|
114
122
|
private
|
115
123
|
|
116
124
|
def player_url
|
117
|
-
|
125
|
+
url+"/system/players/#{name}"
|
118
126
|
end
|
119
127
|
|
120
128
|
def ping(url)
|
data/lib/plex-ruby/episode.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Plex
|
2
2
|
class Episode
|
3
3
|
|
4
|
-
attr_reader :key
|
4
|
+
attr_reader :season, :key
|
5
5
|
|
6
|
-
|
6
|
+
# @param [Season] season this episode belongs to
|
7
|
+
# @param [String] key that we can use to later grab this Episode
|
8
|
+
def initialize(season, key)
|
9
|
+
@season = season
|
7
10
|
@key = key
|
8
11
|
end
|
9
12
|
|
@@ -17,10 +20,14 @@ module Plex
|
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
23
|
+
def url
|
24
|
+
season.url
|
25
|
+
end
|
26
|
+
|
20
27
|
private
|
21
28
|
|
22
29
|
def xml_doc
|
23
|
-
@xml_doc ||= Nokogiri::XML( open(
|
30
|
+
@xml_doc ||= Nokogiri::XML( open(url+key) )
|
24
31
|
end
|
25
32
|
|
26
33
|
def video
|
data/lib/plex-ruby/library.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
module Plex
|
2
2
|
class Library
|
3
3
|
|
4
|
+
attr_reader :server
|
5
|
+
|
6
|
+
# @param [Server] server this libary belongs to
|
7
|
+
def initialize(server)
|
8
|
+
@server = server
|
9
|
+
end
|
10
|
+
|
4
11
|
# Grab a specific section
|
5
12
|
#
|
6
13
|
# @param [String, Fixnum] key of the section we want
|
@@ -30,11 +37,15 @@ module Plex
|
|
30
37
|
"/library/sections"
|
31
38
|
end
|
32
39
|
|
40
|
+
def url
|
41
|
+
server.url
|
42
|
+
end
|
43
|
+
|
33
44
|
private
|
34
45
|
|
35
46
|
def search_sections(doc, key = nil)
|
36
47
|
term = key ? "Directory[@key='#{key}']" : 'Directory'
|
37
|
-
doc.search(term).map { |m| Plex::Section.new(m
|
48
|
+
doc.search(term).map { |m| Plex::Section.new(self, m) }
|
38
49
|
end
|
39
50
|
|
40
51
|
def xml_doc
|
@@ -46,7 +57,7 @@ module Plex
|
|
46
57
|
end
|
47
58
|
|
48
59
|
def base_doc
|
49
|
-
Nokogiri::XML( open(
|
60
|
+
Nokogiri::XML( open(url+key) )
|
50
61
|
end
|
51
62
|
|
52
63
|
|
data/lib/plex-ruby/media.rb
CHANGED
@@ -4,6 +4,8 @@ module Plex
|
|
4
4
|
:audio_codec, :video_codec, :video_resolution, :container, :video_frame_rate,
|
5
5
|
:parts
|
6
6
|
|
7
|
+
# @param [Nokogiri::XML::Element] nokogiri element that represents this
|
8
|
+
# Media
|
7
9
|
def initialize(node)
|
8
10
|
@id = node.attr('id')
|
9
11
|
@durration = node.attr('durration')
|
data/lib/plex-ruby/movie.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
module Plex
|
2
2
|
class Movie
|
3
3
|
|
4
|
-
attr_reader :key
|
4
|
+
attr_reader :section, :key
|
5
5
|
|
6
|
-
|
6
|
+
# @param [Section] section this movie belongs in
|
7
|
+
# @param [String] key to later referance this Movie
|
8
|
+
def initialize(section, key)
|
9
|
+
@section = section
|
7
10
|
@key = key
|
8
11
|
end
|
9
12
|
|
13
|
+
def url
|
14
|
+
section.url
|
15
|
+
end
|
16
|
+
|
10
17
|
# Delegates all method calls to the video object that represents this
|
11
18
|
# movie, if that video object responds to the method.
|
12
19
|
def method_missing(method, *args, &block)
|
@@ -20,7 +27,7 @@ module Plex
|
|
20
27
|
private
|
21
28
|
|
22
29
|
def xml_doc
|
23
|
-
@xml_doc ||= Nokogiri::XML( open(
|
30
|
+
@xml_doc ||= Nokogiri::XML( open(url+key) )
|
24
31
|
end
|
25
32
|
|
26
33
|
def video
|
data/lib/plex-ruby/parser.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Plex
|
2
2
|
class Parser
|
3
3
|
|
4
|
-
attr_reader :node
|
4
|
+
attr_reader :parent, :node
|
5
5
|
|
6
|
-
|
6
|
+
# @param object representing the parent of what we're trying to parse
|
7
|
+
# @param [Nokogiri::XML::Element] nokogiri node to parse
|
8
|
+
def initialize(parent, node)
|
9
|
+
@parent = parent
|
7
10
|
@node = node
|
8
11
|
end
|
9
12
|
|
@@ -17,7 +20,7 @@ module Plex
|
|
17
20
|
def parse
|
18
21
|
case node.name
|
19
22
|
when 'document'
|
20
|
-
Plex::Parser.new(node.root).parse
|
23
|
+
Plex::Parser.new(parent, node.root).parse
|
21
24
|
when 'MediaContainer'
|
22
25
|
parse_media_container
|
23
26
|
when 'Video'
|
@@ -34,7 +37,7 @@ module Plex
|
|
34
37
|
|
35
38
|
def parse_media_container
|
36
39
|
return nil if node.attr('size').to_i == 0
|
37
|
-
node.children.map {|m| Plex::Parser.new(m).parse }.compact
|
40
|
+
node.children.map {|m| Plex::Parser.new(parent, m).parse }.compact
|
38
41
|
end
|
39
42
|
|
40
43
|
def parse_video
|
@@ -49,17 +52,17 @@ module Plex
|
|
49
52
|
end
|
50
53
|
|
51
54
|
def parse_movie
|
52
|
-
Plex::Movie.new( node.attr('key') )
|
55
|
+
Plex::Movie.new( parent, node.attr('key') )
|
53
56
|
end
|
54
57
|
|
55
58
|
def parse_episode
|
56
|
-
Plex::Episode.new( node.attr('key') )
|
59
|
+
Plex::Episode.new( parent, node.attr('key') )
|
57
60
|
end
|
58
61
|
|
59
62
|
def parse_directory
|
60
63
|
case node.attr('type')
|
61
64
|
when 'show'
|
62
|
-
Plex::Show.new( node.attr('key')[0..-10] ) # Remove /children
|
65
|
+
Plex::Show.new( parent, node.attr('key')[0..-10] ) # Remove /children
|
63
66
|
else
|
64
67
|
raise "Unsupported Directory type #{node.attr('type')}"
|
65
68
|
end
|
data/lib/plex-ruby/part.rb
CHANGED
data/lib/plex-ruby/season.rb
CHANGED
@@ -5,9 +5,12 @@ module Plex
|
|
5
5
|
ATTRIBUTES = %w(ratingKey guid type title summary index thumb leafCount
|
6
6
|
viewedLeafCount addedAt updatedAt)
|
7
7
|
|
8
|
-
attr_reader :key
|
8
|
+
attr_reader :show, :key
|
9
9
|
|
10
|
-
|
10
|
+
# @param [Show] show this Season belongs to
|
11
|
+
# @param [String] key to later grab this Season from
|
12
|
+
def initialize(show, key)
|
13
|
+
@show = show
|
11
14
|
@key = key
|
12
15
|
end
|
13
16
|
|
@@ -36,14 +39,18 @@ module Plex
|
|
36
39
|
@episodes = episodes_from_video(children!)
|
37
40
|
end
|
38
41
|
|
42
|
+
def url
|
43
|
+
show.url
|
44
|
+
end
|
45
|
+
|
39
46
|
private
|
40
47
|
|
41
48
|
def base_doc
|
42
|
-
Nokogiri::XML( open(
|
49
|
+
Nokogiri::XML( open(url+key) )
|
43
50
|
end
|
44
51
|
|
45
52
|
def base_children_doc
|
46
|
-
Nokogiri::XML( open(
|
53
|
+
Nokogiri::XML( open(url+key+'/children') )
|
47
54
|
end
|
48
55
|
|
49
56
|
def xml_doc
|
@@ -63,7 +70,7 @@ module Plex
|
|
63
70
|
end
|
64
71
|
|
65
72
|
def episodes_from_video(node)
|
66
|
-
node.search("Video").map { |m| Plex::Episode.new(m.attr('key')) }
|
73
|
+
node.search("Video").map { |m| Plex::Episode.new(self, m.attr('key')) }
|
67
74
|
end
|
68
75
|
|
69
76
|
def directory
|
data/lib/plex-ruby/section.rb
CHANGED
@@ -3,19 +3,23 @@ module Plex
|
|
3
3
|
|
4
4
|
GROUPS = %w(all unwatched newest recentlyAdded recentlyViewed onDeck)
|
5
5
|
|
6
|
-
attr_reader :refreshing, :type, :title, :art, :agent, :scanner,
|
7
|
-
:updated_at
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
6
|
+
attr_reader :library, :refreshing, :type, :title, :art, :agent, :scanner,
|
7
|
+
:language, :updated_at
|
8
|
+
|
9
|
+
# @param [Library] library this Section belongs to
|
10
|
+
# @param [Nokogiri::XML::Element] nokogiri element that represents this
|
11
|
+
# Section
|
12
|
+
def initialize(library, node)
|
13
|
+
@library = library
|
14
|
+
@refreshing = node.attr('refreshing')
|
15
|
+
@key = node.attr('key')
|
16
|
+
@type = node.attr('type')
|
17
|
+
@title = node.attr('title')
|
18
|
+
@art = node.attr('art')
|
19
|
+
@agent = node.attr('agent')
|
20
|
+
@scanner = node.attr('scanner')
|
21
|
+
@language = node.attr('language')
|
22
|
+
@updated_at = node.attr('updatedAt')
|
19
23
|
end
|
20
24
|
|
21
25
|
# NOT IMPLEMENTED
|
@@ -36,7 +40,7 @@ module Plex
|
|
36
40
|
GROUPS.each { |method|
|
37
41
|
class_eval %(
|
38
42
|
def #{Plex.snake_case(method)}
|
39
|
-
Plex::Parser.new( Nokogiri::XML(open(
|
43
|
+
Plex::Parser.new( self, Nokogiri::XML(open(url+key+'/#{method}')) ).parse
|
40
44
|
end
|
41
45
|
)
|
42
46
|
}
|
@@ -44,6 +48,10 @@ module Plex
|
|
44
48
|
def key
|
45
49
|
"/library/sections/#{@key}"
|
46
50
|
end
|
51
|
+
|
52
|
+
def url
|
53
|
+
library.url
|
54
|
+
end
|
47
55
|
|
48
56
|
end
|
49
57
|
end
|
data/lib/plex-ruby/server.rb
CHANGED
@@ -6,14 +6,13 @@ module Plex
|
|
6
6
|
def initialize(host, port)
|
7
7
|
@host = host
|
8
8
|
@port = port
|
9
|
-
Plex.url = "http://#{host}:#{port}"
|
10
9
|
end
|
11
10
|
|
12
11
|
# The library of this server
|
13
12
|
#
|
14
13
|
# @return [Library] this Servers library
|
15
14
|
def library
|
16
|
-
@library ||= Plex::
|
15
|
+
@library ||= Plex::Library.new(self)
|
17
16
|
end
|
18
17
|
|
19
18
|
# The Plex clients that are connected to this Server
|
@@ -28,10 +27,14 @@ module Plex
|
|
28
27
|
@clients = search_clients clients_doc!
|
29
28
|
end
|
30
29
|
|
30
|
+
def url
|
31
|
+
"http://#{host}:#{port}"
|
32
|
+
end
|
33
|
+
|
31
34
|
private
|
32
35
|
|
33
36
|
def clients_base
|
34
|
-
Nokogiri::XML( open(
|
37
|
+
Nokogiri::XML( open(url+'/clients') )
|
35
38
|
end
|
36
39
|
|
37
40
|
def clients_doc
|
@@ -43,7 +46,7 @@ module Plex
|
|
43
46
|
end
|
44
47
|
|
45
48
|
def search_clients(node)
|
46
|
-
node.search('Server').map { |m| Plex::Client.new(m) }
|
49
|
+
node.search('Server').map { |m| Plex::Client.new(self, m) }
|
47
50
|
end
|
48
51
|
|
49
52
|
end
|
data/lib/plex-ruby/show.rb
CHANGED
@@ -6,9 +6,12 @@ module Plex
|
|
6
6
|
art banner theme duration originallyAvailableAt leafCount
|
7
7
|
viewedLeafCount addedAt updatedAt)
|
8
8
|
|
9
|
-
attr_reader :key
|
9
|
+
attr_reader :section, :key
|
10
10
|
|
11
|
-
|
11
|
+
# @param [Section] section this show belongs to
|
12
|
+
# @param [String] key to use to later grab this Show
|
13
|
+
def initialize(section, key)
|
14
|
+
@section = section
|
12
15
|
@key = key
|
13
16
|
end
|
14
17
|
|
@@ -33,14 +36,18 @@ module Plex
|
|
33
36
|
@seasons = search_children children!
|
34
37
|
end
|
35
38
|
|
39
|
+
def url
|
40
|
+
section.url
|
41
|
+
end
|
42
|
+
|
36
43
|
private
|
37
44
|
|
38
45
|
def base_doc
|
39
|
-
Nokogiri::XML( open(
|
46
|
+
Nokogiri::XML( open(url+key) )
|
40
47
|
end
|
41
48
|
|
42
49
|
def children_base
|
43
|
-
Nokogiri::XML( open(
|
50
|
+
Nokogiri::XML( open(url+key+'/children') )
|
44
51
|
end
|
45
52
|
|
46
53
|
def xml_doc
|
@@ -69,7 +76,7 @@ module Plex
|
|
69
76
|
|
70
77
|
def search_children(node)
|
71
78
|
node.search('Directory').map do |season|
|
72
|
-
Plex::Season.new(season.attr('key')[0..-10]) # Remove /children
|
79
|
+
Plex::Season.new(self, season.attr('key')[0..-10]) # Remove /children
|
73
80
|
end
|
74
81
|
end
|
75
82
|
|
data/lib/plex-ruby/stream.rb
CHANGED
data/lib/plex-ruby/version.rb
CHANGED
data/lib/plex-ruby/video.rb
CHANGED
@@ -6,6 +6,8 @@ module Plex
|
|
6
6
|
:duration, :originally_available_at, :updated_at, :media, :genres, :writers,
|
7
7
|
:directors, :roles
|
8
8
|
|
9
|
+
# @param [Nokogiri::XML::Element] nokogiri element that represents this
|
10
|
+
# Video
|
9
11
|
def initialize(node)
|
10
12
|
@rating_key = node.attr('ratingKey')
|
11
13
|
@key = node.attr('key')
|