plex-ruby 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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')
|