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 CHANGED
@@ -14,3 +14,8 @@
14
14
  * Added bang methods that clears caches
15
15
  * Fix naming of 'libary' to 'library'
16
16
  * Moved static content into Constants (Wow!\s)
17
+
18
+ ## 0.3.0
19
+
20
+ * Now allows for multiple servers
21
+ * Fix a misspelling of 'library' that broke the gem (Sorry!)
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'
@@ -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
- def initialize(node)
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(Plex.url+key)}"
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
- Plex.url+"/system/players/#{name}"
125
+ url+"/system/players/#{name}"
118
126
  end
119
127
 
120
128
  def ping(url)
@@ -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
- def initialize(key)
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(Plex.url+key) )
30
+ @xml_doc ||= Nokogiri::XML( open(url+key) )
24
31
  end
25
32
 
26
33
  def video
@@ -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.attributes) }
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(Plex.url+key) )
60
+ Nokogiri::XML( open(url+key) )
50
61
  end
51
62
 
52
63
 
@@ -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')
@@ -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
- def initialize(key)
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(Plex.url+key) )
30
+ @xml_doc ||= Nokogiri::XML( open(url+key) )
24
31
  end
25
32
 
26
33
  def video
@@ -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
- def initialize(node)
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
@@ -3,6 +3,8 @@ module Plex
3
3
 
4
4
  attr_reader :id, :key, :duration, :file, :size, :streams
5
5
 
6
+ # @param [Nokogiri::XML::Element] nokogiri element that represents this
7
+ # part
6
8
  def initialize(node)
7
9
  @id = node.attr('id')
8
10
  @key = node.attr('key')
@@ -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
- def initialize(key)
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(Plex.url+key) )
49
+ Nokogiri::XML( open(url+key) )
43
50
  end
44
51
 
45
52
  def base_children_doc
46
- Nokogiri::XML( open(Plex.url+key+'/children') )
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
@@ -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, :language,
7
- :updated_at
8
-
9
- def initialize(options)
10
- @refreshing = options['refreshing'].value
11
- @key = options['key'].value
12
- @type = options['type'].value
13
- @title = options['title'].value
14
- @art = options['art'].value
15
- @agent = options['agent'].value
16
- @scanner = options['scanner'].value
17
- @language = options['language'].value
18
- @updated_at = options['updatedAt'].value
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(Plex.url+key+'/#{method}')) ).parse
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
@@ -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::Libary.new
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(Plex.url+'/clients') )
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
@@ -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
- def initialize(key)
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(Plex.url+key) )
46
+ Nokogiri::XML( open(url+key) )
40
47
  end
41
48
 
42
49
  def children_base
43
- Nokogiri::XML( open(Plex.url+key+'/children') )
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
 
@@ -3,6 +3,8 @@ module Plex
3
3
 
4
4
  attr_reader :id, :stream_type, :codec, :index, :language, :language_code
5
5
 
6
+ # @param [Nokogiri::XML::Element] nokogiri element that represents this
7
+ # Stream
6
8
  def initialize(node)
7
9
  @id = node.attr('id')
8
10
  @stream_type = node.attr('stream_type')
@@ -1,3 +1,3 @@
1
1
  module Plex
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -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')
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: plex-ruby
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.0
5
+ version: 0.3.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Eric Koslow