plex-ruby 0.1.0 → 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.
- data/.gitignore +1 -0
- data/CHANGELOG.md +11 -0
- data/README.md +8 -0
- data/lib/plex-ruby.rb +10 -1
- data/lib/plex-ruby/client.rb +55 -7
- data/lib/plex-ruby/episode.rb +2 -0
- data/lib/plex-ruby/library.rb +54 -0
- data/lib/plex-ruby/movie.rb +2 -0
- data/lib/plex-ruby/parser.rb +7 -0
- data/lib/plex-ruby/season.rb +47 -7
- data/lib/plex-ruby/section.rb +14 -1
- data/lib/plex-ruby/server.rb +26 -6
- data/lib/plex-ruby/show.rb +48 -12
- data/lib/plex-ruby/version.rb +1 -1
- metadata +2 -2
- data/lib/plex-ruby/libary.rb +0 -25
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -3,3 +3,14 @@
|
|
|
3
3
|
* Initial Release
|
|
4
4
|
* Browsing a library works
|
|
5
5
|
* Sending commands to a clients works intermittently, needs lots of work
|
|
6
|
+
|
|
7
|
+
## 0.1.0
|
|
8
|
+
|
|
9
|
+
* Gem released of RubyGems
|
|
10
|
+
|
|
11
|
+
## 0.2.0
|
|
12
|
+
|
|
13
|
+
* Added documentation
|
|
14
|
+
* Added bang methods that clears caches
|
|
15
|
+
* Fix naming of 'libary' to 'library'
|
|
16
|
+
* Moved static content into Constants (Wow!\s)
|
data/README.md
CHANGED
|
@@ -13,6 +13,14 @@ Add to your `Gemfile` and run the `bundle` command
|
|
|
13
13
|
gem 'plex-ruby'
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
Or
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
gem install plex-ruby
|
|
20
|
+
|
|
21
|
+
require 'plex-ruby'
|
|
22
|
+
```
|
|
23
|
+
|
|
16
24
|
I developed this using Ruby 1.9.2 so no guaranties that it will work with
|
|
17
25
|
lesser versions of Ruby.
|
|
18
26
|
|
data/lib/plex-ruby.rb
CHANGED
|
@@ -4,6 +4,11 @@ require 'cgi'
|
|
|
4
4
|
|
|
5
5
|
module Plex
|
|
6
6
|
|
|
7
|
+
# Converts camel case names that are commonly found in the Plex APIs into
|
|
8
|
+
# ruby friendly names. I.E. playMedia -> play_media
|
|
9
|
+
#
|
|
10
|
+
# @param [String] camel case name to be converted
|
|
11
|
+
# @return [String] snake case form
|
|
7
12
|
def self.snake_case(string)
|
|
8
13
|
string.gsub(/::/, '/').
|
|
9
14
|
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
|
@@ -12,6 +17,10 @@ module Plex
|
|
|
12
17
|
downcase
|
|
13
18
|
end
|
|
14
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
|
|
15
24
|
def self.url
|
|
16
25
|
@@base_url
|
|
17
26
|
end
|
|
@@ -25,7 +34,7 @@ end
|
|
|
25
34
|
require 'plex-ruby/parser'
|
|
26
35
|
require 'plex-ruby/server'
|
|
27
36
|
require 'plex-ruby/client'
|
|
28
|
-
require 'plex-ruby/
|
|
37
|
+
require 'plex-ruby/library'
|
|
29
38
|
require 'plex-ruby/section'
|
|
30
39
|
require 'plex-ruby/video'
|
|
31
40
|
require 'plex-ruby/media'
|
data/lib/plex-ruby/client.rb
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
module Plex
|
|
2
2
|
class Client
|
|
3
3
|
|
|
4
|
+
NAV_METHODS = %w(moveUp moveDown moveLeft moveRight pageUp pageDown nextLetter
|
|
5
|
+
previousLetter select back contextMenu toggleOSD)
|
|
6
|
+
|
|
7
|
+
PLAYBACK_METHODS = %w(play pause stop rewind fastForward stepForward
|
|
8
|
+
bigStepForward stepBack bigStepBack skipNext skipPrevious)
|
|
9
|
+
|
|
4
10
|
attr_reader :name, :host, :address, :port, :machine_identifier, :version
|
|
5
11
|
|
|
6
12
|
def initialize(node)
|
|
@@ -12,8 +18,12 @@ module Plex
|
|
|
12
18
|
@version = node.attr('version')
|
|
13
19
|
end
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
# Navigation methods
|
|
22
|
+
# Sends a movement command to the client to move around menus and such
|
|
23
|
+
#
|
|
24
|
+
# @return [True, nil] true if it worked, nil if something went wrong check
|
|
25
|
+
# the console for the error message
|
|
26
|
+
NAV_METHODS.each { |nav|
|
|
17
27
|
class_eval %(
|
|
18
28
|
def #{Plex.snake_case(nav)}
|
|
19
29
|
ping player_url+'/navigation/#{nav}'
|
|
@@ -21,8 +31,12 @@ module Plex
|
|
|
21
31
|
)
|
|
22
32
|
}
|
|
23
33
|
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
# Playback methods
|
|
35
|
+
# Sends a playback command to the client to play / pause videos and such
|
|
36
|
+
#
|
|
37
|
+
# @return [True, nil] true if it worked, nil if something went wrong check
|
|
38
|
+
# the console for the error message
|
|
39
|
+
PLAYBACK_METHODS.each { |playback|
|
|
26
40
|
class_eval %(
|
|
27
41
|
def #{Plex.snake_case(playback)}
|
|
28
42
|
ping player_url+'/playback/#{playback}'
|
|
@@ -34,6 +48,15 @@ module Plex
|
|
|
34
48
|
ping player_url+"/application/playFile"
|
|
35
49
|
end
|
|
36
50
|
|
|
51
|
+
# Plays a video that is in the library
|
|
52
|
+
#
|
|
53
|
+
# @param [String] the key of the video that we want to play. (see
|
|
54
|
+
# Episode#key) (see Movie#key)
|
|
55
|
+
# @param [String] no clue what this does, its the Plex Remote Command API though
|
|
56
|
+
# @param [String] no clue what this does, its the Plex Remote Command API though
|
|
57
|
+
# @param [String] no clue what this does, its the Plex Remote Command API though
|
|
58
|
+
# @return [True, nil] true if it worked, nil if something went wrong check
|
|
59
|
+
# the console for the error message
|
|
37
60
|
def play_media(key, user_agent = nil, http_cookies = nil, view_offset = nil)
|
|
38
61
|
url = player_url+'/application/playMedia?'
|
|
39
62
|
url += "path=#{CGI::escape(Plex.url+key)}"
|
|
@@ -45,22 +68,47 @@ module Plex
|
|
|
45
68
|
ping url
|
|
46
69
|
end
|
|
47
70
|
|
|
71
|
+
# Take a screenshot of whats on the Plex Client
|
|
72
|
+
#
|
|
73
|
+
# @param [String, Fixnum] width of the screenshot
|
|
74
|
+
# @param [String, Fixnum] height of the screenshot
|
|
75
|
+
# @param [String, Fixnum] quality of the screenshot
|
|
76
|
+
# @return [True, nil] true if it worked, nil if something went wrong check
|
|
77
|
+
# the console for the error message
|
|
48
78
|
def screenshot(width, height, quality)
|
|
49
79
|
url = player_url+'/application/screenshot?'
|
|
50
80
|
url += "width=#{width}"
|
|
51
81
|
url += "&height=#{height}"
|
|
82
|
+
url += "&quality=#{quality}"
|
|
83
|
+
|
|
84
|
+
ping url
|
|
52
85
|
end
|
|
53
86
|
|
|
87
|
+
# Sends a string message to the Plex Client
|
|
88
|
+
#
|
|
89
|
+
# @param [String] message to send
|
|
90
|
+
# @return [True, nil] true if it worked, nil if something went wrong check
|
|
91
|
+
# the console for the error message
|
|
54
92
|
def send_string(text)
|
|
55
|
-
ping player_url+"/application/sendString?text=#{CGI::escape(text)}"
|
|
93
|
+
ping player_url+"/application/sendString?text=#{CGI::escape(text.to_s)}"
|
|
56
94
|
end
|
|
57
95
|
|
|
96
|
+
# Sends a key code to the Plex Client. Key codes represent key presses on
|
|
97
|
+
# a keyboard. Codes are the ASCII value of the letter one wants pressed.
|
|
98
|
+
# It should be noted that the Plex devs have told people to try and avoid
|
|
99
|
+
# using this method when writing plugins, as different users can have
|
|
100
|
+
# different key mappings.
|
|
101
|
+
#
|
|
102
|
+
# @param [String, Fixnum] key code to send
|
|
103
|
+
# @return [True, nil] true if it worked, nil if something went wrong check
|
|
104
|
+
# the console for the error message
|
|
58
105
|
def send_key(code)
|
|
59
|
-
ping player_url+"/application/sendKey?code=#{CGI::escape(code)}"
|
|
106
|
+
ping player_url+"/application/sendKey?code=#{CGI::escape(code.to_s)}"
|
|
60
107
|
end
|
|
61
108
|
|
|
109
|
+
# (see #send_key)
|
|
62
110
|
def send_virtual_key(code)
|
|
63
|
-
ping player_url+"/application/sendVirtualKey?code=#{CGI::escape(code)}"
|
|
111
|
+
ping player_url+"/application/sendVirtualKey?code=#{CGI::escape(code.to_s)}"
|
|
64
112
|
end
|
|
65
113
|
|
|
66
114
|
private
|
data/lib/plex-ruby/episode.rb
CHANGED
|
@@ -7,6 +7,8 @@ module Plex
|
|
|
7
7
|
@key = key
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
# Delegates all method calls to the video object that represents this
|
|
11
|
+
# episode, if that video object responds to the method.
|
|
10
12
|
def method_missing(method, *args, &block)
|
|
11
13
|
if video.respond_to? method
|
|
12
14
|
video.send(method, *args, &block)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Plex
|
|
2
|
+
class Library
|
|
3
|
+
|
|
4
|
+
# Grab a specific section
|
|
5
|
+
#
|
|
6
|
+
# @param [String, Fixnum] key of the section we want
|
|
7
|
+
# @return [Section] section with that key
|
|
8
|
+
def section(id)
|
|
9
|
+
search_sections(xml_doc, id).first
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Cache busting version of #section
|
|
13
|
+
def section!(id)
|
|
14
|
+
search_sections(xml_doc!, id).first
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# A list of sections that are located in this library
|
|
18
|
+
#
|
|
19
|
+
# @return [Array] list of sections
|
|
20
|
+
def sections
|
|
21
|
+
@sections ||= search_sections(xml_doc)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Cache busting version of #sections
|
|
25
|
+
def sections!
|
|
26
|
+
@sections = search_sections(xml_doc!)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def key
|
|
30
|
+
"/library/sections"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def search_sections(doc, key = nil)
|
|
36
|
+
term = key ? "Directory[@key='#{key}']" : 'Directory'
|
|
37
|
+
doc.search(term).map { |m| Plex::Section.new(m.attributes) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def xml_doc
|
|
41
|
+
@xml_doc ||= base_doc
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def xml_doc!
|
|
45
|
+
@xml_doc = base_doc
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def base_doc
|
|
49
|
+
Nokogiri::XML( open(Plex.url+key) )
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/plex-ruby/movie.rb
CHANGED
|
@@ -7,6 +7,8 @@ module Plex
|
|
|
7
7
|
@key = key
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
# Delegates all method calls to the video object that represents this
|
|
11
|
+
# movie, if that video object responds to the method.
|
|
10
12
|
def method_missing(method, *args, &block)
|
|
11
13
|
if video.respond_to? method
|
|
12
14
|
video.send(method, *args, &block)
|
data/lib/plex-ruby/parser.rb
CHANGED
|
@@ -7,6 +7,13 @@ module Plex
|
|
|
7
7
|
@node = node
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
# Parses a XML node and returns the structure it represents. This is
|
|
11
|
+
# currently used to parse Sections as we don't know whether a Section holds
|
|
12
|
+
# a list of Shows or a list of Movies. The parsing is done recursively.
|
|
13
|
+
#
|
|
14
|
+
# @return [Array, Movie, Episode, Show] depending on what node it is given,
|
|
15
|
+
# will return an Array of Movies or Shows, a single Movie, and single
|
|
16
|
+
# Episode, or a single Show
|
|
10
17
|
def parse
|
|
11
18
|
case node.name
|
|
12
19
|
when 'document'
|
data/lib/plex-ruby/season.rb
CHANGED
|
@@ -1,38 +1,78 @@
|
|
|
1
1
|
module Plex
|
|
2
|
-
# Found at /
|
|
2
|
+
# Found at /library/metadata/:key
|
|
3
3
|
class Season
|
|
4
4
|
|
|
5
|
+
ATTRIBUTES = %w(ratingKey guid type title summary index thumb leafCount
|
|
6
|
+
viewedLeafCount addedAt updatedAt)
|
|
7
|
+
|
|
5
8
|
attr_reader :key
|
|
6
9
|
|
|
7
10
|
def initialize(key)
|
|
8
11
|
@key = key
|
|
9
12
|
end
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
# A Season has a key, which allows us to do lazy loading. A season will
|
|
15
|
+
# not be fully loaded unless one of its attributes is called. Then the
|
|
16
|
+
# Season will load itself from its key. Once loaded it caches its self.
|
|
17
|
+
# For every attribute there is a cache busting version wich is just the
|
|
18
|
+
# name of the attribute followed by '!'. For exsample <tt>season.type</tt>
|
|
19
|
+
# and <tt>season.type!</tt>
|
|
20
|
+
ATTRIBUTES.each { |method|
|
|
13
21
|
class_eval %(
|
|
14
22
|
def #{Plex.snake_case(method)}; directory.attr('#{method}') end
|
|
23
|
+
def #{Plex.snake_case(method)}!; directory!.attr('#{method}') end
|
|
15
24
|
)
|
|
16
25
|
}
|
|
17
26
|
|
|
27
|
+
# Returns the list of episodes in the library that are a part of this Season
|
|
28
|
+
#
|
|
29
|
+
# @return [Array] list of episodes in this season that are on the server
|
|
18
30
|
def episodes
|
|
19
|
-
@episodes ||=
|
|
20
|
-
|
|
31
|
+
@episodes ||= episodes_from_video(children)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Cache busting version of #episodes
|
|
35
|
+
def episodes!
|
|
36
|
+
@episodes = episodes_from_video(children!)
|
|
21
37
|
end
|
|
22
38
|
|
|
23
39
|
private
|
|
24
40
|
|
|
41
|
+
def base_doc
|
|
42
|
+
Nokogiri::XML( open(Plex.url+key) )
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def base_children_doc
|
|
46
|
+
Nokogiri::XML( open(Plex.url+key+'/children') )
|
|
47
|
+
end
|
|
48
|
+
|
|
25
49
|
def xml_doc
|
|
26
|
-
@xml_doc ||=
|
|
50
|
+
@xml_doc ||= base_doc
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def xml_doc!
|
|
54
|
+
@xml_doc = base_doc
|
|
27
55
|
end
|
|
28
56
|
|
|
29
57
|
def children
|
|
30
|
-
@children ||=
|
|
58
|
+
@children ||= base_children_doc
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def children!
|
|
62
|
+
@children = base_children_doc
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def episodes_from_video(node)
|
|
66
|
+
node.search("Video").map { |m| Plex::Episode.new(m.attr('key')) }
|
|
31
67
|
end
|
|
32
68
|
|
|
33
69
|
def directory
|
|
34
70
|
@directory ||= xml_doc.search("Directory").first
|
|
35
71
|
end
|
|
36
72
|
|
|
73
|
+
def directory!
|
|
74
|
+
@directory = xml_doc!.search("Directory").first
|
|
75
|
+
end
|
|
76
|
+
|
|
37
77
|
end
|
|
38
78
|
end
|
data/lib/plex-ruby/section.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module Plex
|
|
2
2
|
class Section
|
|
3
3
|
|
|
4
|
+
GROUPS = %w(all unwatched newest recentlyAdded recentlyViewed onDeck)
|
|
5
|
+
|
|
4
6
|
attr_reader :refreshing, :type, :title, :art, :agent, :scanner, :language,
|
|
5
7
|
:updated_at
|
|
6
8
|
|
|
@@ -16,11 +18,22 @@ module Plex
|
|
|
16
18
|
@updated_at = options['updatedAt'].value
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
# NOT IMPLEMENTED
|
|
19
22
|
def refresh(deep = false, force = false)
|
|
20
23
|
end
|
|
21
24
|
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
# Returns a list of shows or movies that are in this Section.
|
|
27
|
+
#
|
|
28
|
+
# all - all videos in this Section
|
|
29
|
+
# unwatched - videos unwatched in this Section
|
|
30
|
+
# newest - most recent videos in this Section
|
|
31
|
+
# recently_added - recently added videos in this Section
|
|
32
|
+
# recently_viewed - recently viewed videos in this Section
|
|
33
|
+
# on_deck - videos that are "on deck" in this Section
|
|
34
|
+
#
|
|
35
|
+
# @return [Array] list of Shows or Movies in that group
|
|
36
|
+
GROUPS.each { |method|
|
|
24
37
|
class_eval %(
|
|
25
38
|
def #{Plex.snake_case(method)}
|
|
26
39
|
Plex::Parser.new( Nokogiri::XML(open(Plex.url+key+'/#{method}')) ).parse
|
data/lib/plex-ruby/server.rb
CHANGED
|
@@ -9,21 +9,41 @@ module Plex
|
|
|
9
9
|
Plex.url = "http://#{host}:#{port}"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
# The library of this server
|
|
13
|
+
#
|
|
14
|
+
# @return [Library] this Servers library
|
|
15
|
+
def library
|
|
16
|
+
@library ||= Plex::Libary.new
|
|
13
17
|
end
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
# The Plex clients that are connected to this Server
|
|
20
|
+
#
|
|
21
|
+
# @return [Array] list of Clients connected to this server
|
|
22
|
+
def clients
|
|
23
|
+
@clients ||= search_clients clients_doc
|
|
17
24
|
end
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
# Cache busting version of #clients
|
|
27
|
+
def clients!
|
|
28
|
+
@clients = search_clients clients_doc!
|
|
21
29
|
end
|
|
22
30
|
|
|
23
31
|
private
|
|
24
32
|
|
|
33
|
+
def clients_base
|
|
34
|
+
Nokogiri::XML( open(Plex.url+'/clients') )
|
|
35
|
+
end
|
|
36
|
+
|
|
25
37
|
def clients_doc
|
|
26
|
-
@clients_doc ||=
|
|
38
|
+
@clients_doc ||= clients_base
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def clients_doc!
|
|
42
|
+
@clients_doc = clients_base
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def search_clients(node)
|
|
46
|
+
node.search('Server').map { |m| Plex::Client.new(m) }
|
|
27
47
|
end
|
|
28
48
|
|
|
29
49
|
end
|
data/lib/plex-ruby/show.rb
CHANGED
|
@@ -1,40 +1,76 @@
|
|
|
1
1
|
module Plex
|
|
2
|
-
# Found at /
|
|
2
|
+
# Found at /library/metadata/:key
|
|
3
3
|
class Show
|
|
4
4
|
|
|
5
|
+
ATTRIBUTES = %w(guid studio title contentRating summary index rating year thumb
|
|
6
|
+
art banner theme duration originallyAvailableAt leafCount
|
|
7
|
+
viewedLeafCount addedAt updatedAt)
|
|
8
|
+
|
|
5
9
|
attr_reader :key
|
|
6
10
|
|
|
7
11
|
def initialize(key)
|
|
8
12
|
@key = key
|
|
9
13
|
end
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
# A Show has a key, which allows us to do lazy loading. A Show will
|
|
16
|
+
# not be fully loaded unless one of its attributes is called. Then the
|
|
17
|
+
# Show will load itself from its key. Once loaded it caches its self.
|
|
18
|
+
ATTRIBUTES.each { |method|
|
|
14
19
|
class_eval %(
|
|
15
20
|
def #{Plex.snake_case(method)}; @#{method} ||= directory.attr('#{method}') end
|
|
21
|
+
def #{Plex.snake_case(method)}!; @#{method} = directory!.attr('#{method}') end
|
|
16
22
|
)
|
|
17
23
|
}
|
|
18
24
|
|
|
25
|
+
# The list of seasons in the library that belong to this Show
|
|
26
|
+
#
|
|
27
|
+
# @return [Array] list of Seasons that are a part of this Show
|
|
19
28
|
def seasons
|
|
20
|
-
@seasons ||=
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
@seasons ||= search_children children
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def seasons!
|
|
33
|
+
@seasons = search_children children!
|
|
24
34
|
end
|
|
25
35
|
|
|
26
36
|
private
|
|
27
37
|
|
|
38
|
+
def base_doc
|
|
39
|
+
Nokogiri::XML( open(Plex.url+key) )
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def children_base
|
|
43
|
+
Nokogiri::XML( open(Plex.url+key+'/children') )
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def xml_doc
|
|
47
|
+
@xml_doc ||= base_doc
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def xml_doc!
|
|
51
|
+
@xml_doc = base_doc
|
|
52
|
+
end
|
|
53
|
+
|
|
28
54
|
def children
|
|
29
|
-
@children ||=
|
|
55
|
+
@children ||= children_base
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def children!
|
|
59
|
+
@children = children_base
|
|
30
60
|
end
|
|
31
61
|
|
|
32
62
|
def directory
|
|
33
63
|
@directory ||= xml_doc.search('Directory').first
|
|
34
64
|
end
|
|
35
|
-
|
|
36
|
-
def
|
|
37
|
-
@
|
|
65
|
+
|
|
66
|
+
def directory!
|
|
67
|
+
@directory = xml_doc!.search('Directory').first
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def search_children(node)
|
|
71
|
+
node.search('Directory').map do |season|
|
|
72
|
+
Plex::Season.new(season.attr('key')[0..-10]) # Remove /children
|
|
73
|
+
end
|
|
38
74
|
end
|
|
39
75
|
|
|
40
76
|
end
|
data/lib/plex-ruby/version.rb
CHANGED
metadata
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: plex-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease:
|
|
5
|
-
version: 0.
|
|
5
|
+
version: 0.2.0
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Eric Koslow
|
|
@@ -65,7 +65,7 @@ files:
|
|
|
65
65
|
- lib/plex-ruby.rb
|
|
66
66
|
- lib/plex-ruby/client.rb
|
|
67
67
|
- lib/plex-ruby/episode.rb
|
|
68
|
-
- lib/plex-ruby/
|
|
68
|
+
- lib/plex-ruby/library.rb
|
|
69
69
|
- lib/plex-ruby/media.rb
|
|
70
70
|
- lib/plex-ruby/movie.rb
|
|
71
71
|
- lib/plex-ruby/null.rb
|
data/lib/plex-ruby/libary.rb
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module Plex
|
|
2
|
-
class Libary
|
|
3
|
-
|
|
4
|
-
def section(id)
|
|
5
|
-
xml_doc.search("Directory[@key='#{id}']").map do |m|
|
|
6
|
-
Plex::Section.new(m.attributes)
|
|
7
|
-
end.first
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def sections
|
|
11
|
-
xml_doc.search('Directory').map { |m| Plex::Section.new(m.attributes) }
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def key
|
|
15
|
-
"/library/sections"
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
def xml_doc
|
|
21
|
-
@xml_doc ||= Nokogiri::XML( open(Plex.url+key) )
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
end
|
|
25
|
-
end
|