plex-ruby 1.0.0 → 1.1.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.
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Plex-Ruby
1
+ # Plex-Ruby [![Build Status](https://secure.travis-ci.org/ekosz/Plex-Ruby.png)](https://secure.travis-ci.org/ekosz/Plex-Ruby.png)
2
2
 
3
3
  A handy gem for working with Plex within Ruby. Tries to emulate and document
4
4
  all of the Plex APIs using simple ruby code. I will try and keep it as
@@ -7,19 +7,19 @@ 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 :server, :name, :host, :address, :port, :machine_identifier, :version
10
+ ATTRIBUTES = %w(name host address port machineIdentifier version)
11
+
12
+ attr_reader *ATTRIBUTES.map {|m| Plex.snake_case(m) }
13
+ attr_reader :server
11
14
 
12
15
 
13
16
  # @param [Server] server this client belongs to
14
17
  # @param [Nokogiri::XML::Element] nokogiri element to build from
15
18
  def initialize(server, node)
16
19
  @server = server
17
- @name = node.attr('name')
18
- @host = node.attr('host')
19
- @address = node.attr('address')
20
- @port = node.attr('port')
21
- @machine_identifier = node.attr('machineIdentifier')
22
- @version = node.attr('version')
20
+ ATTRIBUTES.each { |e|
21
+ instance_variable_set("@#{Plex.snake_case(e)}", node.attr(e))
22
+ }
23
23
  end
24
24
 
25
25
  # Navigation methods
@@ -1,22 +1,18 @@
1
1
  module Plex
2
2
  class Media
3
- attr_reader :id, :durration, :bitrate, :aspect_ratio, :audio_channels,
4
- :audio_codec, :video_codec, :video_resolution, :container, :video_frame_rate,
5
- :parts
3
+
4
+ ATTRIBUTES = %w(id durration bitrate aspectRatio audioChannels
5
+ audioCodec videoCodec videoResolution container videoFrameRate)
6
+
7
+ attr_reader *ATTRIBUTES.map {|m| Plex.snake_case(m) }
8
+ attr_reader :parts
6
9
 
7
10
  # @param [Nokogiri::XML::Element] nokogiri element that represents this
8
11
  # Media
9
12
  def initialize(node)
10
- @id = node.attr('id')
11
- @durration = node.attr('durration')
12
- @bitrate = node.attr('bitrate')
13
- @aspect_ratio = node.attr('aspectRatio')
14
- @audio_channels = node.attr('audioChannels')
15
- @audio_codec = node.attr('audioCodec')
16
- @video_codec = node.attr('videoCodec')
17
- @video_resolution = node.attr('videoResolution')
18
- @container = node.attr('container')
19
- @video_frame_rate = node.attr('videoFrameRate')
13
+ ATTRIBUTES.each { |e|
14
+ instance_variable_set("@#{Plex.snake_case(e)}", node.attr(e))
15
+ }
20
16
 
21
17
  @parts = node.search("Part").map { |m| Plex::Part.new(m) }
22
18
  end
@@ -1,16 +1,17 @@
1
1
  module Plex
2
2
  class Part
3
3
 
4
- attr_reader :id, :key, :duration, :file, :size, :streams
4
+ ATTRIBUTES = %w(id key duration file size)
5
+
6
+ attr_reader *ATTRIBUTES.map {|m| Plex.snake_case(m) }
7
+ attr_reader :streams
5
8
 
6
9
  # @param [Nokogiri::XML::Element] nokogiri element that represents this
7
10
  # part
8
11
  def initialize(node)
9
- @id = node.attr('id')
10
- @key = node.attr('key')
11
- @duration = node.attr('duration')
12
- @file = node.attr('file')
13
- @size = node.attr('size')
12
+ ATTRIBUTES.each { |e|
13
+ instance_variable_set("@#{Plex.snake_case(e)}", node.attr(e))
14
+ }
14
15
 
15
16
  @streams = node.search('Stream').map { |m| Plex::Stream.new(m) }
16
17
  end
@@ -3,23 +3,21 @@ module Plex
3
3
 
4
4
  GROUPS = %w(all unwatched newest recentlyAdded recentlyViewed onDeck)
5
5
 
6
- attr_reader :library, :refreshing, :key, :type, :title, :art, :agent, :scanner,
7
- :language, :updated_at
6
+ ATTRIBUTES = %w(refreshing key type title art agent scanner language updatedAt)
7
+
8
+ CATEGORIES = %w(collection firstCharacter genre year contentRating folder)
9
+
10
+ attr_reader *ATTRIBUTES.map {|m| Plex.snake_case(m) }
11
+ attr_reader :library
8
12
 
9
13
  # @param [Library] library this Section belongs to
10
14
  # @param [Nokogiri::XML::Element] nokogiri element that represents this
11
15
  # Section
12
16
  def initialize(library, node)
13
17
  @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')
18
+ ATTRIBUTES.each { |e|
19
+ instance_variable_set("@#{Plex.snake_case(e)}", node.attr(e))
20
+ }
23
21
  end
24
22
 
25
23
  # NOT IMPLEMENTED
@@ -45,6 +43,39 @@ module Plex
45
43
  )
46
44
  }
47
45
 
46
+ # Find TV Shows / Episodes by categories
47
+ #
48
+ # Format:
49
+ # #{category}s - Grab the keys => title in that category
50
+ # #{category}s! - cache busing version of #{category}s
51
+ # by_#{category}(key) - all shows / movies by that key
52
+ #
53
+ # Example:
54
+ #
55
+ # library.section(2).by_year(2008) # List of TV Shows from 2008
56
+ # library.section(1).by_first_character("H") # movies starting with 'H'
57
+ # library.section(2).genres # Array of Hashes explaining all of the genres
58
+ #
59
+ # collection - I'm not sure
60
+ # first_character - the first letter of the title of the video
61
+ # genre - self explanatory
62
+ # year - year first shown
63
+ # content_rating - TV-14, TV-MA, etc
64
+ # folder - where the video is stored
65
+ CATEGORIES.each { |method|
66
+ class_eval %(
67
+ def #{Plex.snake_case(method)}s
68
+ @#{Plex.snake_case(method)}s ||= grab_keys('#{method})'
69
+ end
70
+ def #{Plex.snake_case(method)}s!
71
+ @#{Plex.snake_case(method)}s = grab_keys('#{method})'
72
+ end
73
+ def by_#{Plex.snake_case(method)}(val)
74
+ Plex::Parser.new( self, Nokogiri::XML(open(url+key+"/#{method}/\#{val}")) ).parse
75
+ end
76
+ )
77
+ }
78
+
48
79
  def key
49
80
  "/library/sections/#{@key}"
50
81
  end
@@ -61,5 +92,17 @@ module Plex
61
92
  end
62
93
  end
63
94
 
95
+ private
96
+
97
+ def grab_keys(action)
98
+ Nokogiri::XML(open(url+key+"/#{action}")).search('Directory').map do |node|
99
+ {
100
+ key: node.attr('key'),
101
+ title: node.attr('title')
102
+ }
103
+ end
104
+ end
105
+
106
+
64
107
  end
65
108
  end
@@ -1,17 +1,16 @@
1
1
  module Plex
2
2
  class Stream
3
3
 
4
- attr_reader :id, :stream_type, :codec, :index, :language, :language_code
4
+ ATTRIBUTES = %w(id streamType codec index language languageCode)
5
+
6
+ attr_reader *ATTRIBUTES.map {|m| Plex.snake_case(m) }
5
7
 
6
8
  # @param [Nokogiri::XML::Element] nokogiri element that represents this
7
9
  # Stream
8
10
  def initialize(node)
9
- @id = node.attr('id')
10
- @stream_type = node.attr('stream_type')
11
- @codec = node.attr('codec')
12
- @index = node.attr('index')
13
- @language = node.attr('language')
14
- @language_code = node.attr('language_code')
11
+ ATTRIBUTES.each { |e|
12
+ instance_variable_set("@#{Plex.snake_case(e)}", node.attr(e))
13
+ }
15
14
  end
16
15
 
17
16
  def ==(other)
@@ -1,3 +1,3 @@
1
1
  module Plex
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -1,31 +1,19 @@
1
1
  module Plex
2
2
  class Video
3
-
4
- attr_reader :rating_key, :key, :studio, :type, :title, :title_sort,
5
- :content_rating, :summary, :rating, :view_count, :year, :tagline, :thumb, :art,
6
- :duration, :originally_available_at, :updated_at, :media, :genres, :writers,
7
- :directors, :roles
3
+
4
+ ATTRIBUTES = %w(ratingKey key studio type title titleSort contentRating summary
5
+ rating viewCount year tagline thumb art duration
6
+ originallyAvailableAt updatedAt)
7
+
8
+ attr_reader *ATTRIBUTES.map {|m| Plex.snake_case(m) }
9
+ attr_reader :media, :genres, :writers, :directors, :roles
8
10
 
9
11
  # @param [Nokogiri::XML::Element] nokogiri element that represents this
10
12
  # Video
11
13
  def initialize(node)
12
- @rating_key = node.attr('ratingKey')
13
- @key = node.attr('key')
14
- @studio = node.attr('studio')
15
- @type = node.attr('type')
16
- @title = node.attr('title')
17
- @title_sort = node.attr('titleSort')
18
- @content_rating = node.attr('contentRating')
19
- @summary = node.attr('summary')
20
- @rating = node.attr('rating')
21
- @view_count = node.attr('viewCount')
22
- @year = node.attr('year')
23
- @tagline = node.attr('tagline')
24
- @thumb = node.attr('thumb')
25
- @art = node.attr('art')
26
- @duration = node.attr('duration')
27
- @originally_available_at = node.attr('originallyAvailableAt')
28
- @updated_at = node.attr('updatedAt')
14
+ ATTRIBUTES.each { |e|
15
+ instance_variable_set("@#{Plex.snake_case(e)}", node.attr(e))
16
+ }
29
17
 
30
18
  @media = Plex::Media.new(node.search('Media').first)
31
19
  @genres = node.search('Genre').map { |m| Plex::Genre.new(m) }
@@ -20,5 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  s.add_development_dependency 'minitest'
23
+ s.add_development_dependency "rake"
24
+ s.add_development_dependency "fakeweb"
23
25
  s.add_runtime_dependency 'nokogiri'
24
26
  end
@@ -0,0 +1,76 @@
1
+ require 'test_helper'
2
+ require 'fakeweb'
3
+
4
+ describe Plex::Client do
5
+ before do
6
+ @server = FakeParent.new
7
+ @client = Plex::Client.new(@server, FakeNode.new(FAKE_CLIENT_NODE_HASH))
8
+ FakeWeb.register_uri(:get, %r|http://localhost:32400|, :body => "")
9
+ end
10
+
11
+ after do
12
+ FakeWeb.clean_registry
13
+ end
14
+
15
+ Plex::Client::NAV_METHODS.each { |method|
16
+ it "should properly communicate its ##{Plex.snake_case(method)} method" do
17
+ assert @client.send(Plex.snake_case(method).to_sym)
18
+ FakeWeb.last_request.path.must_equal "/system/players/#{@client.name}/navigation/#{method}"
19
+ end
20
+ }
21
+
22
+ Plex::Client::PLAYBACK_METHODS.each { |method|
23
+ it "should properly communicate its ##{Plex.snake_case(method)} method" do
24
+ assert @client.send(Plex.snake_case(method).to_sym)
25
+ FakeWeb.last_request.path.must_equal "/system/players/#{@client.name}/playback/#{method}"
26
+ end
27
+ }
28
+
29
+ it "should properly commnicate its #play_file method" do
30
+ assert @client.play_file
31
+ FakeWeb.last_request.path.must_equal "/system/players/#{@client.name}/application/playFile"
32
+ end
33
+
34
+ it "should properly commnicate its #play_media method" do
35
+ key = '/metadata/10'
36
+ assert @client.play_media(key)
37
+ FakeWeb.last_request.path.must_equal(
38
+ "/system/players/#{@client.name}/application/playMedia?path=#{CGI::escape(@client.url+key)}&key=#{CGI::escape(key)}"
39
+ )
40
+ end
41
+
42
+ it "should properly commnicate its #screenshot method" do
43
+ assert @client.screenshot(100, 100, 75)
44
+ FakeWeb.last_request.path.must_equal(
45
+ "/system/players/#{@client.name}/application/screenshot?width=100&height=100&quality=75"
46
+ )
47
+ end
48
+
49
+ it "should properly commnicate its #send_string method" do
50
+ assert @client.send_string(35)
51
+ FakeWeb.last_request.path.must_equal(
52
+ "/system/players/#{@client.name}/application/sendString?text=35"
53
+ )
54
+ end
55
+
56
+ it "should properly commnicate its #send_key method" do
57
+ assert @client.send_key(70)
58
+ FakeWeb.last_request.path.must_equal(
59
+ "/system/players/#{@client.name}/application/sendKey?code=70"
60
+ )
61
+ end
62
+
63
+ it "should properly commnicate its #send_virtual_key method" do
64
+ assert @client.send_virtual_key(70)
65
+ FakeWeb.last_request.path.must_equal(
66
+ "/system/players/#{@client.name}/application/sendVirtualKey?code=70"
67
+ )
68
+ end
69
+
70
+ it "should remember its parent (server)" do
71
+ @client.server.must_equal @server
72
+ end
73
+
74
+ end
75
+
76
+
@@ -3,7 +3,8 @@ require 'test_helper'
3
3
  describe Plex::Episode do
4
4
 
5
5
  before do
6
- @episode = Plex::Episode.new(FakeParent.new, '/libary/metadata/6')
6
+ @season = FakeParent.new
7
+ @episode = Plex::Episode.new(@season, '/libary/metadata/6')
7
8
  end
8
9
 
9
10
  it "should pass the proper method calls to its video object" do
@@ -12,8 +13,7 @@ describe Plex::Episode do
12
13
  "@video", fake_video
13
14
  )
14
15
 
15
- %w(studio type title title_sort content_rating summary rating view_count year
16
- tagline thumb art duration originally_available_at updated_at).each { |method|
16
+ (Plex::Video::ATTRIBUTES - %w(key)).map {|m| Plex.snake_case(m) }.each { |method|
17
17
  @episode.send(method.to_sym).must_equal fake_video.send(method.to_sym)
18
18
  }
19
19
 
@@ -29,4 +29,8 @@ describe Plex::Episode do
29
29
 
30
30
  end
31
31
 
32
+ it "should remember its parent (season)" do
33
+ @episode.season.must_equal @season
34
+ end
35
+
32
36
  end
@@ -26,6 +26,15 @@ class FakeParent
26
26
 
27
27
  end
28
28
 
29
+ FAKE_CLIENT_NODE_HASH = {
30
+ name: 'koslow.office',
31
+ host: '10.0.0.24',
32
+ address: '10.0.0.24',
33
+ port: '3000',
34
+ machine_identifier: 'f11283e2-a274-4c86-9a0a-23336c2d9e53',
35
+ version: '0.9.5.2-06ca164'
36
+ }
37
+
29
38
  FAKE_SHOW_NODE_HASH = {
30
39
  Directory: FakeNode.new({
31
40
  guid: 'com.plexapp.agents.thetvdb://73545/1?lang=en',
@@ -2,7 +2,8 @@ require 'test_helper'
2
2
 
3
3
  describe Plex::Library do
4
4
  before do
5
- @library = Plex::Library.new(FakeParent.new)
5
+ @server = FakeParent.new
6
+ @library = Plex::Library.new(@server)
6
7
  @library.instance_variable_set("@xml_doc", FakeNode.new(FAKE_LIBRARY_NODE_HASH))
7
8
  end
8
9
 
@@ -18,4 +19,8 @@ describe Plex::Library do
18
19
  Plex::Section.new(nil, FakeNode.new(FAKE_SECTION_NODE_HASH))
19
20
  )
20
21
  end
22
+
23
+ it "should remember its parent (server)" do
24
+ @library.server.must_equal @server
25
+ end
21
26
  end
@@ -5,8 +5,7 @@ describe Plex::Media do
5
5
  @media = Plex::Media.new( FakeNode.new(FAKE_MEDIA_NODE_HASH) )
6
6
  end
7
7
 
8
- %w(id durration bitrate aspect_ratio audio_channels audio_codec video_codec
9
- video_resolution container video_frame_rate).each { |method|
8
+ Plex::Media::ATTRIBUTES.map {|m| Plex.snake_case(m) }.each { |method|
10
9
  it "should properly respond to ##{method}" do
11
10
  @media.send(method.to_sym).must_equal FAKE_MEDIA_NODE_HASH[method.to_sym]
12
11
  end
@@ -3,7 +3,8 @@ require 'test_helper'
3
3
  describe Plex::Movie do
4
4
 
5
5
  before do
6
- @movie = Plex::Movie.new(FakeParent.new, '/libary/metadata/6')
6
+ @section = FakeParent.new
7
+ @movie = Plex::Movie.new(@section, '/libary/metadata/6')
7
8
  end
8
9
 
9
10
  it "should pass the proper method calls to its video object" do
@@ -12,8 +13,7 @@ describe Plex::Movie do
12
13
  "@video", fake_video
13
14
  )
14
15
 
15
- %w(studio type title title_sort content_rating summary rating view_count year
16
- tagline thumb art duration originally_available_at updated_at).each { |method|
16
+ (Plex::Video::ATTRIBUTES - %w(key)).map {|m| Plex.snake_case(m) }.each { |method|
17
17
  @movie.send(method.to_sym).must_equal fake_video.send(method.to_sym)
18
18
  }
19
19
 
@@ -29,4 +29,8 @@ describe Plex::Movie do
29
29
 
30
30
  end
31
31
 
32
+ it "should remember its parent (section)" do
33
+ @movie.section.must_equal @section
34
+ end
35
+
32
36
  end
@@ -5,7 +5,7 @@ describe Plex::Part do
5
5
  @part = Plex::Part.new( FakeNode.new(FAKE_PART_NODE_HASH) )
6
6
  end
7
7
 
8
- %w(id key duration file size).each { |method|
8
+ Plex::Part::ATTRIBUTES.map {|m| Plex.snake_case(m) }.each { |method|
9
9
  it "should properly respond to ##{method}" do
10
10
  @part.send(method.to_sym).must_equal FAKE_PART_NODE_HASH[method.to_sym]
11
11
  end
@@ -2,7 +2,8 @@ require 'test_helper'
2
2
 
3
3
  describe Plex::Season do
4
4
  before do
5
- @season = Plex::Season.new(FakeParent.new, '/library/metadata/10')
5
+ @show = FakeParent.new
6
+ @season = Plex::Season.new(@show, '/library/metadata/10')
6
7
  @season.instance_variable_set("@xml_doc", FakeNode.new(FAKE_SEASON_NODE_HASH))
7
8
  end
8
9
 
@@ -21,4 +22,8 @@ describe Plex::Season do
21
22
  )
22
23
  end
23
24
 
25
+ it "should remember its parent (show)" do
26
+ @season.show.must_equal @show
27
+ end
28
+
24
29
  end
@@ -2,12 +2,18 @@ require 'test_helper'
2
2
 
3
3
  describe Plex::Section do
4
4
  before do
5
- @section = Plex::Section.new(FakeParent.new, FakeNode.new(FAKE_SECTION_NODE_HASH))
5
+ @library = FakeParent.new
6
+ @section = Plex::Section.new(@library, FakeNode.new(FAKE_SECTION_NODE_HASH))
6
7
  end
7
8
 
8
- %w(refreshing type title art agent scanner language updated_at).each { |method|
9
+ (Plex::Section::ATTRIBUTES - %w(key)).map{|m| Plex.snake_case(m)}.each { |method|
9
10
  it "should respond to ##{method}" do
10
11
  @section.send(method.to_sym).must_equal FAKE_SECTION_NODE_HASH[method.to_sym]
11
12
  end
12
13
  }
14
+
15
+ it "should remember its parent (library)" do
16
+ @section.library.must_equal @library
17
+ end
18
+
13
19
  end
@@ -2,7 +2,8 @@ require 'test_helper'
2
2
 
3
3
  describe Plex::Show do
4
4
  before do
5
- @show = Plex::Show.new(FakeParent.new, '/library/metadata/10')
5
+ @section = FakeParent.new
6
+ @show = Plex::Show.new(@section, '/library/metadata/10')
6
7
  @show.instance_variable_set("@xml_doc", FakeNode.new(FAKE_SHOW_NODE_HASH))
7
8
  end
8
9
 
@@ -21,4 +22,8 @@ describe Plex::Show do
21
22
  )
22
23
  end
23
24
 
25
+ it "should remember its parent (section)" do
26
+ @show.section.must_equal @section
27
+ end
28
+
24
29
  end
@@ -5,7 +5,7 @@ describe Plex::Stream do
5
5
  @stream = Plex::Stream.new( FakeNode.new(FAKE_STREAM_NODE_HASH) )
6
6
  end
7
7
 
8
- %w(id stream_type codec index language language_code).each { |method|
8
+ Plex::Stream::ATTRIBUTES.map{|m| Plex.snake_case(m)}.each { |method|
9
9
  it "should properly respond to ##{method}" do
10
10
  @stream.send(method.to_sym).must_equal FAKE_STREAM_NODE_HASH[method.to_sym]
11
11
  end
@@ -6,8 +6,7 @@ describe Plex::Video do
6
6
  @video = Plex::Video.new( FakeNode.new(FAKE_VIDEO_NODE_HASH) )
7
7
  end
8
8
 
9
- %w(key studio type title title_sort content_rating summary rating view_count year
10
- tagline thumb art duration originally_available_at updated_at).each { |method|
9
+ Plex::Video::ATTRIBUTES.map {|m| Plex.snake_case(m) }.each { |method|
11
10
  it "should correctly respond to ##{method}" do
12
11
  @video.send(method.to_sym).must_equal FAKE_VIDEO_NODE_HASH[method.to_sym]
13
12
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: plex-ruby
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.0.0
5
+ version: 1.1.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Eric Koslow
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-12-09 00:00:00 -05:00
13
+ date: 2011-12-12 00:00:00 -05:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -25,7 +25,7 @@ dependencies:
25
25
  type: :development
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
- name: nokogiri
28
+ name: rake
29
29
  prerelease: false
30
30
  requirement: &id002 !ruby/object:Gem::Requirement
31
31
  none: false
@@ -33,8 +33,30 @@ dependencies:
33
33
  - - ">="
34
34
  - !ruby/object:Gem::Version
35
35
  version: "0"
36
- type: :runtime
36
+ type: :development
37
37
  version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: fakeweb
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: nokogiri
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :runtime
59
+ version_requirements: *id004
38
60
  description: Extracts the Plex API into easy to write ruby code
39
61
  email:
40
62
  - ekoslow@gmail.com
@@ -46,6 +68,7 @@ extra_rdoc_files: []
46
68
 
47
69
  files:
48
70
  - .gitignore
71
+ - .travis.yml
49
72
  - CHANGELOG.md
50
73
  - Gemfile
51
74
  - LICENSE
@@ -57,7 +80,6 @@ files:
57
80
  - lib/plex-ruby/library.rb
58
81
  - lib/plex-ruby/media.rb
59
82
  - lib/plex-ruby/movie.rb
60
- - lib/plex-ruby/null.rb
61
83
  - lib/plex-ruby/parser.rb
62
84
  - lib/plex-ruby/part.rb
63
85
  - lib/plex-ruby/season.rb
@@ -1,13 +0,0 @@
1
- class Null
2
-
3
- def self.to_s; "" end
4
- def self.to_i; 0 end
5
- def self.to_a; [] end
6
- def self.to_f; 0.0 end
7
- def self.!@; true end
8
- def self.nil?; true end
9
- def self.present?; false end
10
- def self.blank?; true end
11
- def self.empty?; true end
12
-
13
- end