plex-ruby 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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