sofa 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.document +5 -0
  2. data/.yardopts +6 -0
  3. data/Rakefile +76 -0
  4. data/doc/Sofa.html +85 -0
  5. data/doc/Sofa/Mapping.html +168 -0
  6. data/doc/Sofa/Mapping/ClassMethods.html +314 -0
  7. data/doc/Sofa/Mapping/InstanceMethods.html +358 -0
  8. data/doc/Sofa/TVRage.html +85 -0
  9. data/doc/Sofa/TVRage/Episode.html +358 -0
  10. data/doc/Sofa/TVRage/Schedule.html +207 -0
  11. data/doc/Sofa/TVRage/Season.html +236 -0
  12. data/doc/Sofa/TVRage/Show.html +904 -0
  13. data/doc/Sofa/TVRage/Show/ShowNotFound.html +92 -0
  14. data/doc/Sofa/Version.html +100 -0
  15. data/doc/_index.html +206 -0
  16. data/doc/class_list.html +137 -0
  17. data/doc/css/common.css +1 -0
  18. data/doc/css/full_list.css +23 -0
  19. data/doc/css/style.css +261 -0
  20. data/doc/file.README.html +120 -0
  21. data/doc/file_list.html +29 -0
  22. data/doc/index.html +120 -0
  23. data/doc/js/app.js +91 -0
  24. data/doc/js/full_list.js +39 -0
  25. data/doc/js/jquery.js +19 -0
  26. data/doc/method_list.html +192 -0
  27. data/doc/top-level-namespace.html +80 -0
  28. data/lib/sofa.rb +7 -0
  29. data/lib/sofa/mapping.rb +108 -0
  30. data/lib/sofa/tvrage.rb +10 -0
  31. data/lib/sofa/tvrage/episode.rb +56 -0
  32. data/lib/sofa/tvrage/schedule.rb +25 -0
  33. data/lib/sofa/tvrage/season.rb +36 -0
  34. data/lib/sofa/tvrage/show.rb +132 -0
  35. data/lib/sofa/version.rb +8 -0
  36. data/sofa.gemspec +113 -0
  37. data/spec/fixtures/tvrage/cases/castle.xml +228 -0
  38. data/spec/fixtures/tvrage/cases/community.xml +109 -0
  39. data/spec/fixtures/tvrage/cases/live_with_regis_and_kelly.xml +56237 -0
  40. data/spec/fixtures/tvrage/episode_info.xml +30 -0
  41. data/spec/fixtures/tvrage/episode_list.xml +1183 -0
  42. data/spec/fixtures/tvrage/episode_list_one_season.xml +17 -0
  43. data/spec/fixtures/tvrage/episode_list_two_episodes.xml +25 -0
  44. data/spec/fixtures/tvrage/full_schedule.xml +4731 -0
  45. data/spec/fixtures/tvrage/full_show_info.xml +1291 -0
  46. data/spec/fixtures/tvrage/quickinfo.html +17 -0
  47. data/spec/fixtures/tvrage/quickinfo_missing.html +1 -0
  48. data/spec/fixtures/tvrage/search.xml +151 -0
  49. data/spec/fixtures/tvrage/show_info.xml +42 -0
  50. data/spec/fixtures/tvrage/show_info_blank.xml +3 -0
  51. data/spec/fixtures/tvrage/single_episode.xml +8 -0
  52. data/spec/spec.opts +1 -0
  53. metadata +57 -32
@@ -0,0 +1,10 @@
1
+ require 'httparty'
2
+
3
+ module Sofa
4
+ module TVRage
5
+ autoload :Schedule, 'sofa/tvrage/schedule'
6
+ autoload :Show, 'sofa/tvrage/show'
7
+ autoload :Season, 'sofa/tvrage/season'
8
+ autoload :Episode, 'sofa/tvrage/episode'
9
+ end
10
+ end
@@ -0,0 +1,56 @@
1
+ module Sofa
2
+ module TVRage
3
+ # This class holds the XML information of a single episode as per the TVRage API.
4
+ #
5
+ # @see http://services.tvrage.com/index.php?page=public TVRage API : Episode List
6
+ class Episode
7
+ include Mapping
8
+
9
+ include HTTParty
10
+ format :xml
11
+ base_uri 'services.tvrage.com'
12
+
13
+ class << self
14
+ # Gets the info for a Episode.
15
+ #
16
+ # @param sid [String] The show's id
17
+ # @return [Hash] The parsed XML
18
+ # @see http://services.tvrage.com/feeds/episodeinfo.php?sid=2930&ep=2x04
19
+ def info(sid, season_no, ep_num)
20
+ xml = get('/feeds/episodeinfo.php', :query => {:sid => sid, :ep => "#{season_no}x#{ep_num}"})
21
+ xml["show"]
22
+ end
23
+ end
24
+
25
+
26
+ # @see Sofa::Mapping
27
+ maps(
28
+ :epnum => :num,
29
+ :seasonnum => :num_in_season,
30
+ :prodnum => :prod_num,
31
+ :airdate => :air_date,
32
+ :link => nil,
33
+ :title => nil
34
+ )
35
+
36
+ # The season number of the Season this Episode belongs to.
37
+ # Not actually a part of the TVRage API, but it's used to inject
38
+ # the +season_num+ when looping through Episodes in a Season.
39
+ attr_reader :season_num
40
+
41
+ # Returns a new instance of Episode, mapping info from the TVRage API
42
+ #
43
+ # @param info [Hash<Symbol, Object>] Info to initialize with
44
+ # @option info [String] :epnum The episode number in the context of all episodes
45
+ # @option info [String] :seasonnum The episode number in the context of its season
46
+ # @option info [String] :prodnum
47
+ # @option info [String] :airdate The date the episode airs
48
+ # @option info [String] :link The TVRage page for this Episode
49
+ # @option info [String] :title The title of this Episode
50
+ # @option info [String] :season_num The season number of the Season this Episode belongs to
51
+ def initialize(info)
52
+ update_with_mapping(info)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,25 @@
1
+ module Sofa
2
+ module TVRage
3
+ # This class will hold the full/quick schedule information as per the TVRage API.
4
+ #
5
+ # @see http://services.tvrage.com/index.php?page=public&go=fullschedule TVRage API : Full Schedule
6
+ # @see http://services.tvrage.com/index.php?page=public&go=quickschedule TV Rage API : Quick Schedule
7
+ class Schedule
8
+ include HTTParty
9
+ format :xml
10
+ base_uri 'services.tvrage.com/feeds'
11
+
12
+ class << self
13
+ # Gets the full schedule for country
14
+ #
15
+ # @param country [String] The country to query in (US, UK, NL)
16
+ # @return [Hash] The parsed XML of schedule information
17
+ # @see http://services.tvrage.com/feeds/fullschedule.php?country=US US's Full Schedule
18
+ def full(country)
19
+ xml = get("/fullschedule.php", :query => {:country => country})
20
+ xml["schedule"]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ module Sofa
2
+ module TVRage
3
+ # This class holds the XML information of a single season as per the TVRage API.
4
+ #
5
+ # @see http://services.tvrage.com/index.php?page=public TVRage API : Episode List
6
+ class Season
7
+ include Mapping
8
+
9
+ # Maps :no to itself
10
+ # @see Sofa::Mapping
11
+ maps(:no => nil)
12
+
13
+ # Maps :episode to :episodes
14
+ # @see Sofa::Mapping
15
+ # @yieldparam value [Hash, Array] A Hash of info if there's only one. An Array of info if there's multiple
16
+ # @yieldreturn [Array] A list of episodes initialized with value
17
+ maps(:episode => :episodes) do |value|
18
+ case value
19
+ when Hash
20
+ [Episode.new(value)]
21
+ when Array
22
+ value.map { |info| Episode.new(info) }
23
+ end
24
+ end
25
+
26
+ # Returns a new instance of Season, mapping info from the TVRage API
27
+ #
28
+ # @param info [Hash<Symbol, Object>] Info to initialize with
29
+ # @option info [String] :no The season number
30
+ # @option info [String] :episode The collection of episodes
31
+ def initialize(info)
32
+ update_with_mapping(info)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,132 @@
1
+ module Sofa
2
+ module TVRage
3
+ # This class holds the XML information of a single Show as per the TVRage API.
4
+ # It's also the root point for communicating with the API.
5
+ #
6
+ # @see http://services.tvrage.com/index.php?page=public TVRage API
7
+ class Show
8
+ include HTTParty
9
+ format :xml
10
+ base_uri 'services.tvrage.com'
11
+
12
+ class << self
13
+ # Gets the info for a Show.
14
+ #
15
+ # @param sid [String] The show's id
16
+ # @return [Hash] The parsed XML
17
+ # @see http://services.tvrage.com/feeds/showinfo.php?sid=15614 Chuck's Show Info
18
+ def info(sid)
19
+ xml = get('/feeds/showinfo.php', :query => {:sid => sid})
20
+ xml["Showinfo"]
21
+ end
22
+
23
+ # Gets the full show info (info + season list + episode list) for a Show.
24
+ #
25
+ # @param sid [String] The show's id
26
+ # @return [Hash] The parsed XML
27
+ # @see http://services.tvrage.com/feeds/full_show_info.php?sid=15614 Chuck's Full Show Info
28
+ def full_info(sid)
29
+ xml = get('/feeds/full_show_info.php', :query => {:sid => sid})
30
+ xml["Show"]
31
+ end
32
+
33
+ # Gets the episode list for a Show.
34
+ #
35
+ # @param sid [String] The show's id
36
+ # @return [Hash] The parsed XML
37
+ # @see http://services.tvrage.com/feeds/episode_list.php?sid=15614 Chuck's Episode List
38
+ def episode_list(sid)
39
+ xml = get('/feeds/episode_list.php', :query => {:sid => sid})
40
+ xml["Show"]
41
+ end
42
+
43
+ # Finds the Show by name using TVRage's Quickinfo API.
44
+ #
45
+ # @param name [String] The name of the show to search for
46
+ # @option options [Boolean] :greedy Whether or not to eager load the Season and Episode info
47
+ # @return [Show] The show with id parsed from the Quickinfo search
48
+ # @see http://services.tvrage.com/index.php?page=public&go=quickinfo TVRage Quickinfo API
49
+ # @see http://services.tvrage.com/tools/quickinfo.php?show=Chuck Chuck's Quickinfo
50
+ def by_name(name, options = {})
51
+ html = get('/tools/quickinfo.php', :query => {:show => name}, :format => :html)
52
+ show_info = Crack::XML.parse(html)["pre"]
53
+ raise ShowNotFound unless show_info
54
+ id = show_info.split("\n").first.gsub(%r{^Show ID@}, '').strip
55
+ Show.new(id, options)
56
+ end
57
+ end
58
+
59
+ include Mapping
60
+
61
+ # @see Sofa::Mapping
62
+ maps(
63
+ :ended => nil,
64
+ :showid => :show_id,
65
+ :showname => :name,
66
+ :name => nil,
67
+ :showlink => :show_link,
68
+ :seasons => nil,
69
+ :started => nil,
70
+ :startdate => :start_date,
71
+ :ended => nil,
72
+ :origin_country => nil,
73
+ :status => nil,
74
+ :classification => nil,
75
+ :runtime => :run_time,
76
+ :network => nil,
77
+ :airtime => :air_time,
78
+ :airday => :air_day,
79
+ :timezone => :time_zone
80
+ )
81
+ maps(:genres => nil) { |value| value["genre"] }
82
+ maps(:akas => nil) { |value| value["aka"] }
83
+
84
+ # Maps :Episodelist to :season_list
85
+ # @see Sofa::Mapping
86
+ # @yieldparam value [Hash, Array] A Hash of info if there's only one. An Array of info if there's multiple
87
+ # @yieldreturn [Array] A list of seasons initialized with value
88
+ maps(:Episodelist => :season_list) do |value|
89
+ case seasons = value["Season"]
90
+ when Hash
91
+ [Season.new(seasons)]
92
+ when Array
93
+ seasons.map { |info| Season.new(info) }
94
+ end
95
+ end
96
+
97
+ # Stores all the info that was greedy-loaded
98
+ #
99
+ # @return [Hash] The full show info (including seasons and episodes)
100
+ # @see Show.full_info
101
+ attr_accessor :greedy
102
+
103
+ # Returns a new instance of Show, loading and then mapping info from the TVRage API.
104
+ #
105
+ # @param id [String] The show_id as per the TVRage API
106
+ # @option options [Boolean] :greedy Whether or not to eager load the Season and Episode info
107
+ def initialize(id, options = {})
108
+ raise RuntimeError.new("id is required") unless (@show_id = id)
109
+ klass = self.class
110
+ if options[:greedy]
111
+ update_with_mapping(@greedy = klass.full_info(@show_id))
112
+ else
113
+ update_with_mapping(klass.info(@show_id))
114
+ end
115
+ end
116
+
117
+ # @return [Array] The list of seasons
118
+ def season_list
119
+ update_with_mapping(self.class.episode_list(@show_id)) unless @season_list
120
+ @season_list
121
+ end
122
+
123
+ # @return [Array] The list of episodes
124
+ def episode_list
125
+ season_list.map { |season| season.episodes }.flatten
126
+ end
127
+
128
+ class ShowNotFound < RuntimeError #:nodoc:
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,8 @@
1
+ module Sofa
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 2
6
+ STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
+ end
8
+ end
data/sofa.gemspec ADDED
@@ -0,0 +1,113 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "sofa"
8
+ s.version = "0.1.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Henry Hsu"]
12
+ s.date = "2013-01-22"
13
+ s.description = "A simple Ruby library for the TVRage API."
14
+ s.email = "henry@qlane.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".yardopts",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "doc/Sofa.html",
26
+ "doc/Sofa/Mapping.html",
27
+ "doc/Sofa/Mapping/ClassMethods.html",
28
+ "doc/Sofa/Mapping/InstanceMethods.html",
29
+ "doc/Sofa/TVRage.html",
30
+ "doc/Sofa/TVRage/Episode.html",
31
+ "doc/Sofa/TVRage/Schedule.html",
32
+ "doc/Sofa/TVRage/Season.html",
33
+ "doc/Sofa/TVRage/Show.html",
34
+ "doc/Sofa/TVRage/Show/ShowNotFound.html",
35
+ "doc/Sofa/Version.html",
36
+ "doc/_index.html",
37
+ "doc/class_list.html",
38
+ "doc/css/common.css",
39
+ "doc/css/full_list.css",
40
+ "doc/css/style.css",
41
+ "doc/file.README.html",
42
+ "doc/file_list.html",
43
+ "doc/index.html",
44
+ "doc/js/app.js",
45
+ "doc/js/full_list.js",
46
+ "doc/js/jquery.js",
47
+ "doc/method_list.html",
48
+ "doc/top-level-namespace.html",
49
+ "lib/sofa.rb",
50
+ "lib/sofa/mapping.rb",
51
+ "lib/sofa/tvrage.rb",
52
+ "lib/sofa/tvrage/episode.rb",
53
+ "lib/sofa/tvrage/schedule.rb",
54
+ "lib/sofa/tvrage/season.rb",
55
+ "lib/sofa/tvrage/show.rb",
56
+ "lib/sofa/version.rb",
57
+ "sofa.gemspec",
58
+ "spec/fixtures/tvrage/cases/castle.xml",
59
+ "spec/fixtures/tvrage/cases/community.xml",
60
+ "spec/fixtures/tvrage/cases/live_with_regis_and_kelly.xml",
61
+ "spec/fixtures/tvrage/episode_info.xml",
62
+ "spec/fixtures/tvrage/episode_list.xml",
63
+ "spec/fixtures/tvrage/episode_list_one_season.xml",
64
+ "spec/fixtures/tvrage/episode_list_two_episodes.xml",
65
+ "spec/fixtures/tvrage/full_schedule.xml",
66
+ "spec/fixtures/tvrage/full_show_info.xml",
67
+ "spec/fixtures/tvrage/quickinfo.html",
68
+ "spec/fixtures/tvrage/quickinfo_missing.html",
69
+ "spec/fixtures/tvrage/search.xml",
70
+ "spec/fixtures/tvrage/show_info.xml",
71
+ "spec/fixtures/tvrage/show_info_blank.xml",
72
+ "spec/fixtures/tvrage/single_episode.xml",
73
+ "spec/sofa/mapping_spec.rb",
74
+ "spec/sofa/tvrage/cases_spec.rb",
75
+ "spec/sofa/tvrage/episode_spec.rb",
76
+ "spec/sofa/tvrage/schedule_spec.rb",
77
+ "spec/sofa/tvrage/season_spec.rb",
78
+ "spec/sofa/tvrage/show_spec.rb",
79
+ "spec/sofa/version_spec.rb",
80
+ "spec/sofa_spec.rb",
81
+ "spec/spec.opts",
82
+ "spec/spec_helper.rb"
83
+ ]
84
+ s.homepage = "http://github.com/hsume2/sofa"
85
+ s.require_paths = ["lib"]
86
+ s.rubygems_version = "1.8.24"
87
+ s.summary = "A Ruby library for the TVRage API."
88
+
89
+ if s.respond_to? :specification_version then
90
+ s.specification_version = 3
91
+
92
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
93
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
94
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
95
+ s.add_development_dependency(%q<mocha>, [">= 0"])
96
+ s.add_development_dependency(%q<fakeweb>, [">= 0"])
97
+ s.add_development_dependency(%q<yard>, [">= 0"])
98
+ else
99
+ s.add_dependency(%q<httparty>, [">= 0"])
100
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
101
+ s.add_dependency(%q<mocha>, [">= 0"])
102
+ s.add_dependency(%q<fakeweb>, [">= 0"])
103
+ s.add_dependency(%q<yard>, [">= 0"])
104
+ end
105
+ else
106
+ s.add_dependency(%q<httparty>, [">= 0"])
107
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
108
+ s.add_dependency(%q<mocha>, [">= 0"])
109
+ s.add_dependency(%q<fakeweb>, [">= 0"])
110
+ s.add_dependency(%q<yard>, [">= 0"])
111
+ end
112
+ end
113
+
@@ -0,0 +1,228 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Show>
3
+ <name>Castle (2009)</name>
4
+ <totalseasons>2</totalseasons>
5
+ <showid>19267</showid>
6
+ <showlink>http://tvrage.com/Castle</showlink>
7
+ <started>Mar/09/2009</started>
8
+ <ended/>
9
+ <image>http://images.tvrage.com/shows/20/19267.jpg</image>
10
+ <origin_country>US</origin_country>
11
+ <status>Returning Series</status>
12
+ <classification>Scripted</classification>
13
+ <genres>
14
+ <genre>Crime</genre>
15
+ <genre>Drama</genre>
16
+ <genre>Mystery</genre>
17
+ </genres>
18
+ <runtime>60</runtime>
19
+ <network country="US">ABC</network>
20
+ <airtime>22:00</airtime>
21
+ <airday>Monday</airday>
22
+ <timezone>GMT-5 -DST</timezone>
23
+ <Episodelist>
24
+ <Season no="1">
25
+ <episode>
26
+ <epnum>1</epnum>
27
+ <seasonnum>01</seasonnum>
28
+ <prodnum>101</prodnum>
29
+ <airdate>2009-03-09</airdate>
30
+ <link>http://www.tvrage.com/Castle/episodes/703445</link>
31
+ <title>Flowers for Your Grave</title>
32
+ <screencap>http://images.tvrage.com/screencaps/97/19267/703445.jpg</screencap>
33
+ </episode>
34
+ <episode>
35
+ <epnum>2</epnum>
36
+ <seasonnum>02</seasonnum>
37
+ <prodnum>102</prodnum>
38
+ <airdate>2009-03-16</airdate>
39
+ <link>http://www.tvrage.com/Castle/episodes/781859</link>
40
+ <title>Nanny McDead</title>
41
+ <screencap>http://images.tvrage.com/screencaps/97/19267/781859.jpg</screencap>
42
+ </episode>
43
+ <episode>
44
+ <epnum>3</epnum>
45
+ <seasonnum>03</seasonnum>
46
+ <prodnum>103</prodnum>
47
+ <airdate>2009-03-23</airdate>
48
+ <link>http://www.tvrage.com/Castle/episodes/781860</link>
49
+ <title>Hedge Fund Homeboys</title>
50
+ <screencap>http://images.tvrage.com/screencaps/97/19267/781860.jpg</screencap>
51
+ </episode>
52
+ <episode>
53
+ <epnum>4</epnum>
54
+ <seasonnum>04</seasonnum>
55
+ <prodnum>104</prodnum>
56
+ <airdate>2009-03-30</airdate>
57
+ <link>http://www.tvrage.com/Castle/episodes/781861</link>
58
+ <title>Hell Hath No Fury</title>
59
+ <screencap>http://images.tvrage.com/screencaps/97/19267/781861.jpg</screencap>
60
+ </episode>
61
+ <episode>
62
+ <epnum>5</epnum>
63
+ <seasonnum>05</seasonnum>
64
+ <prodnum>105</prodnum>
65
+ <airdate>2009-04-06</airdate>
66
+ <link>http://www.tvrage.com/Castle/episodes/781862</link>
67
+ <title>A Chill Goes Through Her Veins</title>
68
+ <screencap>http://images.tvrage.com/screencaps/97/19267/781862.jpg</screencap>
69
+ </episode>
70
+ <episode>
71
+ <epnum>6</epnum>
72
+ <seasonnum>06</seasonnum>
73
+ <prodnum>106</prodnum>
74
+ <airdate>2009-04-13</airdate>
75
+ <link>http://www.tvrage.com/Castle/episodes/781864</link>
76
+ <title>Always Buy Retail</title>
77
+ </episode>
78
+ <episode>
79
+ <epnum>7</epnum>
80
+ <seasonnum>07</seasonnum>
81
+ <prodnum>107</prodnum>
82
+ <airdate>2009-04-20</airdate>
83
+ <link>http://www.tvrage.com/Castle/episodes/781863</link>
84
+ <title>Home Is Where the Heart Stops</title>
85
+ <screencap>http://images.tvrage.com/screencaps/97/19267/781863.jpg</screencap>
86
+ </episode>
87
+ <episode>
88
+ <epnum>8</epnum>
89
+ <seasonnum>08</seasonnum>
90
+ <prodnum>108</prodnum>
91
+ <airdate>2009-04-27</airdate>
92
+ <link>http://www.tvrage.com/Castle/episodes/781865</link>
93
+ <title>Ghosts</title>
94
+ <screencap>http://images.tvrage.com/screencaps/97/19267/781865.jpg</screencap>
95
+ </episode>
96
+ <episode>
97
+ <epnum>9</epnum>
98
+ <seasonnum>09</seasonnum>
99
+ <prodnum>109</prodnum>
100
+ <airdate>2009-05-04</airdate>
101
+ <link>http://www.tvrage.com/Castle/episodes/781866</link>
102
+ <title>Little Girl Lost</title>
103
+ <screencap>http://images.tvrage.com/screencaps/97/19267/781866.jpg</screencap>
104
+ </episode>
105
+ <episode>
106
+ <epnum>10</epnum>
107
+ <seasonnum>10</seasonnum>
108
+ <prodnum>110</prodnum>
109
+ <airdate>2009-05-11</airdate>
110
+ <link>http://www.tvrage.com/Castle/episodes/781867</link>
111
+ <title>A Death in the Family</title>
112
+ <screencap>http://images.tvrage.com/screencaps/97/19267/781867.jpg</screencap>
113
+ </episode>
114
+ </Season>
115
+ <Season no="2">
116
+ <episode>
117
+ <epnum>11</epnum>
118
+ <seasonnum>01</seasonnum>
119
+ <prodnum>201</prodnum>
120
+ <airdate>2009-09-21</airdate>
121
+ <link>http://www.tvrage.com/Castle/episodes/1064812069</link>
122
+ <title>Deep in Death</title>
123
+ <screencap>http://images.tvrage.com/screencaps/97/19267/1064812069.jpg</screencap>
124
+ </episode>
125
+ <episode>
126
+ <epnum>12</epnum>
127
+ <seasonnum>02</seasonnum>
128
+ <prodnum>202</prodnum>
129
+ <airdate>2009-09-28</airdate>
130
+ <link>http://www.tvrage.com/Castle/episodes/1064824888</link>
131
+ <title>The Double Down</title>
132
+ <screencap>http://images.tvrage.com/screencaps/97/19267/1064824888.jpg</screencap>
133
+ </episode>
134
+ <episode>
135
+ <epnum>13</epnum>
136
+ <seasonnum>03</seasonnum>
137
+ <prodnum>203</prodnum>
138
+ <airdate>2009-10-05</airdate>
139
+ <link>http://www.tvrage.com/Castle/episodes/1064824889</link>
140
+ <title>Inventing the Girl</title>
141
+ <screencap>http://images.tvrage.com/screencaps/97/19267/1064824889.jpg</screencap>
142
+ </episode>
143
+ <episode>
144
+ <epnum>14</epnum>
145
+ <seasonnum>04</seasonnum>
146
+ <prodnum>204</prodnum>
147
+ <airdate>2009-10-12</airdate>
148
+ <link>http://www.tvrage.com/Castle/episodes/1064824890</link>
149
+ <title>Fool Me Once</title>
150
+ <screencap>http://images.tvrage.com/screencaps/97/19267/1064824890.jpg</screencap>
151
+ </episode>
152
+ <episode>
153
+ <epnum>15</epnum>
154
+ <seasonnum>05</seasonnum>
155
+ <prodnum>205</prodnum>
156
+ <airdate>2009-10-19</airdate>
157
+ <link>http://www.tvrage.com/Castle/episodes/1064842856</link>
158
+ <title>When the Bough Breaks</title>
159
+ <screencap>http://images.tvrage.com/screencaps/97/19267/1064842856.jpg</screencap>
160
+ </episode>
161
+ <episode>
162
+ <epnum>16</epnum>
163
+ <seasonnum>06</seasonnum>
164
+ <prodnum>206</prodnum>
165
+ <airdate>2009-10-26</airdate>
166
+ <link>http://www.tvrage.com/Castle/episodes/1064842857</link>
167
+ <title>Vampire Weekend</title>
168
+ <screencap>http://images.tvrage.com/screencaps/97/19267/1064842857.jpg</screencap>
169
+ </episode>
170
+ <episode>
171
+ <epnum>17</epnum>
172
+ <seasonnum>07</seasonnum>
173
+ <prodnum>207</prodnum>
174
+ <airdate>2009-11-02</airdate>
175
+ <link>http://www.tvrage.com/Castle/episodes/1064842858</link>
176
+ <title>Famous Last Words</title>
177
+ </episode>
178
+ <episode>
179
+ <epnum>18</epnum>
180
+ <seasonnum>08</seasonnum>
181
+ <prodnum>208</prodnum>
182
+ <airdate>2009-11-09</airdate>
183
+ <link>http://www.tvrage.com/Castle/episodes/1064842859</link>
184
+ <title>Kill the Messenger</title>
185
+ </episode>
186
+ <episode>
187
+ <epnum>19</epnum>
188
+ <seasonnum>09</seasonnum>
189
+ <prodnum>209</prodnum>
190
+ <airdate>2009-11-16</airdate>
191
+ <link>http://www.tvrage.com/Castle/episodes/1064842860</link>
192
+ <title>Love Me Dead</title>
193
+ </episode>
194
+ <episode>
195
+ <epnum>20</epnum>
196
+ <seasonnum>10</seasonnum>
197
+ <prodnum>210</prodnum>
198
+ <airdate>2009-11-23</airdate>
199
+ <link>http://www.tvrage.com/Castle/episodes/1064842861</link>
200
+ <title>One Man's Treasure</title>
201
+ </episode>
202
+ <episode>
203
+ <epnum>21</epnum>
204
+ <seasonnum>11</seasonnum>
205
+ <prodnum>211</prodnum>
206
+ <airdate>2009-11-30</airdate>
207
+ <link>http://www.tvrage.com/Castle/episodes/1064842862</link>
208
+ <title>The Fifth Bullet</title>
209
+ </episode>
210
+ <episode>
211
+ <epnum>22</epnum>
212
+ <seasonnum>12</seasonnum>
213
+ <prodnum>212</prodnum>
214
+ <airdate>0000-00-00</airdate>
215
+ <link>http://www.tvrage.com/Castle/episodes/1064842863</link>
216
+ <title>Season 2, Episode 12</title>
217
+ </episode>
218
+ <episode>
219
+ <epnum>23</epnum>
220
+ <seasonnum>13</seasonnum>
221
+ <prodnum>213</prodnum>
222
+ <airdate>0000-00-00</airdate>
223
+ <link>http://www.tvrage.com/Castle/episodes/1064842864</link>
224
+ <title>Season 2, Episode 13</title>
225
+ </episode>
226
+ </Season>
227
+ </Episodelist>
228
+ </Show>