em-sofa 0.1.1
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/.document +5 -0
- data/.gitignore +22 -0
- data/.yardopts +6 -0
- data/LICENSE +20 -0
- data/README.md +110 -0
- data/Rakefile +75 -0
- data/doc/Em-sofa/Mapping.html +168 -0
- data/doc/Em-sofa/Mapping/ClassMethods.html +314 -0
- data/doc/Em-sofa/Mapping/InstanceMethods.html +358 -0
- data/doc/Em-sofa/TVRage.html +85 -0
- data/doc/Em-sofa/TVRage/Episode.html +358 -0
- data/doc/Em-sofa/TVRage/Schedule.html +207 -0
- data/doc/Em-sofa/TVRage/Season.html +236 -0
- data/doc/Em-sofa/TVRage/Show.html +904 -0
- data/doc/Em-sofa/TVRage/Show/ShowNotFound.html +92 -0
- data/doc/Em-sofa/Version.html +100 -0
- data/doc/Sofa.html +85 -0
- data/doc/_index.html +233 -0
- data/doc/class_list.html +36 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +50 -0
- data/doc/css/style.css +277 -0
- data/doc/file.README.html +150 -0
- data/doc/file_list.html +38 -0
- data/doc/index.html +150 -0
- data/doc/js/app.js +138 -0
- data/doc/js/full_list.js +117 -0
- data/doc/js/jquery.js +19 -0
- data/doc/method_list.html +195 -0
- data/doc/top-level-namespace.html +88 -0
- data/lib/em-sofa.rb +8 -0
- data/lib/em-sofa/mapping.rb +108 -0
- data/lib/em-sofa/tvrage.rb +14 -0
- data/lib/em-sofa/tvrage/episode.rb +41 -0
- data/lib/em-sofa/tvrage/schedule.rb +28 -0
- data/lib/em-sofa/tvrage/season.rb +38 -0
- data/lib/em-sofa/tvrage/show.rb +193 -0
- data/lib/em-sofa/version.rb +10 -0
- data/spec/fixtures/tvrage/cases/castle.xml +228 -0
- data/spec/fixtures/tvrage/cases/community.xml +109 -0
- data/spec/fixtures/tvrage/cases/live_with_regis_and_kelly.xml +56237 -0
- data/spec/fixtures/tvrage/episode_list.xml +1183 -0
- data/spec/fixtures/tvrage/episode_list_one_season.xml +17 -0
- data/spec/fixtures/tvrage/episode_list_two_episodes.xml +25 -0
- data/spec/fixtures/tvrage/full_schedule.xml +4731 -0
- data/spec/fixtures/tvrage/full_show_info.xml +1291 -0
- data/spec/fixtures/tvrage/quickinfo.html +17 -0
- data/spec/fixtures/tvrage/quickinfo_missing.html +1 -0
- data/spec/fixtures/tvrage/search.xml +151 -0
- data/spec/fixtures/tvrage/show_info.xml +42 -0
- data/spec/fixtures/tvrage/show_info_blank.xml +3 -0
- data/spec/fixtures/tvrage/single_episode.xml +8 -0
- data/spec/sofa/mapping_spec.rb +82 -0
- data/spec/sofa/tvrage/cases_spec.rb +29 -0
- data/spec/sofa/tvrage/episode_spec.rb +45 -0
- data/spec/sofa/tvrage/schedule_spec.rb +17 -0
- data/spec/sofa/tvrage/season_spec.rb +61 -0
- data/spec/sofa/tvrage/show_spec.rb +201 -0
- data/spec/sofa/version_spec.rb +11 -0
- data/spec/sofa_spec.rb +5 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +20 -0
- metadata +165 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Sofa
|
3
|
+
module TVRage
|
4
|
+
# This class will hold the full/quick schedule information as per the TVRage API.
|
5
|
+
#
|
6
|
+
# @see http://services.tvrage.com/index.php?page=public&go=fullschedule TVRage API : Full Schedule
|
7
|
+
# @see http://services.tvrage.com/index.php?page=public&go=quickschedule TV Rage API : Quick Schedule
|
8
|
+
class Schedule
|
9
|
+
Base_Uri = 'services.tvrage.com/feeds'
|
10
|
+
|
11
|
+
extend TVRage
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# Gets the full schedule for country
|
15
|
+
#
|
16
|
+
# @param country [String] The country to query in (US, UK, NL)
|
17
|
+
# @param &block [Block] Called back with result unless fibered
|
18
|
+
# @return [Hash] The parsed XML of schedule information
|
19
|
+
# @see http://services.tvrage.com/feeds/fullschedule.php?country=US US's Full Schedule
|
20
|
+
def full(country, &block)
|
21
|
+
return Request.fibered(method(__method__), country) if defined? Fiber and Fiber.respond_to? :current and not block
|
22
|
+
Request.new(Base_Uri, '/fullschedule.php', block, :return_element => 'schedule', :country => country)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Sofa
|
3
|
+
module TVRage
|
4
|
+
# This class holds the XML information of a single season as per the TVRage API.
|
5
|
+
#
|
6
|
+
# @see http://services.tvrage.com/index.php?page=public TVRage API : Episode List
|
7
|
+
class Season
|
8
|
+
include Mapping
|
9
|
+
|
10
|
+
# Maps :no to itself
|
11
|
+
# @see EM:Sofa::Mapping
|
12
|
+
maps(:no => nil)
|
13
|
+
|
14
|
+
# Maps :episode to :episodes
|
15
|
+
# @see EM:Sofa::Mapping
|
16
|
+
# @yieldparam value [Hash, Array] A Hash of info if there's only one. An Array of info if there's multiple
|
17
|
+
# @yieldreturn [Array] A list of episodes initialized with value
|
18
|
+
maps(:episode => :episodes) do |value|
|
19
|
+
case value
|
20
|
+
when Hash
|
21
|
+
[Episode.new(value)]
|
22
|
+
when Array
|
23
|
+
value.map { |info| Episode.new(info) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns a new instance of Season, mapping info from the TVRage API
|
28
|
+
#
|
29
|
+
# @param info [Hash<Symbol, Object>] Info to initialize with
|
30
|
+
# @option info [String] :no The season number
|
31
|
+
# @option info [String] :episode The collection of episodes
|
32
|
+
def initialize(info)
|
33
|
+
update_with_mapping(info)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Sofa
|
3
|
+
module TVRage
|
4
|
+
# This class holds the XML information of a single Show as per the TVRage API.
|
5
|
+
# It's also the root point for communicating with the API.
|
6
|
+
#
|
7
|
+
# @see http://services.tvrage.com/index.php?page=public TVRage API
|
8
|
+
class Show
|
9
|
+
Base_Uri = 'services.tvrage.com'
|
10
|
+
|
11
|
+
extend TVRage
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# Gets the info for a Show.
|
15
|
+
#
|
16
|
+
# @param sid [String] The show's id
|
17
|
+
# @param &block [Block] Called back with the parsed XML when successful unless fibered
|
18
|
+
# @return [EM:TVRage::Request] TVRage request object or result hash if fibered
|
19
|
+
# @see http://services.tvrage.com/feeds/showinfo.php?sid=15614 Chuck's Show Info
|
20
|
+
def info(sid, &block)
|
21
|
+
return fibered_async(__method__, sid, options) if defined? Fiber and Fiber.respond_to? :current and not block
|
22
|
+
raise ArgumentError, "No block given for completion callback" unless block
|
23
|
+
Request.new(Base_Uri, '/feeds/showinfo.php', block, :return_element => 'Showinfo', :sid => sid)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Gets the full show info (info + season list + episode list) for a Show.
|
27
|
+
#
|
28
|
+
# @param sid [String] The show's id
|
29
|
+
# @param &block [Block] Called back with the parsed XML when successful unless fibered
|
30
|
+
# @return [EM:TVRage::Request] TVRage request object or result hash if fibered
|
31
|
+
# @see http://services.tvrage.com/feeds/full_show_info.php?sid=15614 Chuck's Full Show Info
|
32
|
+
def full_info(sid, &block)
|
33
|
+
return fibered_async(__method__, sid, options) if defined? Fiber and Fiber.respond_to? :current and not block
|
34
|
+
raise ArgumentError, "No block given for completion callback" unless block
|
35
|
+
Request.new(Base_Uri, '/feeds/full_show_info.php', block, :return_element => 'Show', :sid => sid)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Gets the episode list for a Show.
|
39
|
+
#
|
40
|
+
# @param sid [String] The show's id
|
41
|
+
# @param &block [Block] Called back with the parsed XML when successful unless fibered
|
42
|
+
# @return [EM:TVRage::Request] TVRage request object or result hash if fibered
|
43
|
+
# @see http://services.tvrage.com/feeds/episode_list.php?sid=15614 Chuck's Episode List
|
44
|
+
def episode_list(sid, &block)
|
45
|
+
return Request.fibered(method(__method__), sid) if defined? Fiber and Fiber.respond_to? :current and not block
|
46
|
+
raise ArgumentError, "No block given for completion callback" unless block
|
47
|
+
Request.new(Base_Uri, '/feeds/episode_list.php', block, :return_element => 'Show', :sid => sid)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Finds the Show by name using TVRage's Quickinfo API.
|
51
|
+
#
|
52
|
+
# @param name [String] The name of the show to search for
|
53
|
+
# @option options [Boolean] :greedy Whether or not to eager load the Season and Episode info
|
54
|
+
# @param &block [Block] Called back with the show with id parsed from the Quickinfo search unless fibered
|
55
|
+
# @return [EM:TVRage::Request] TVRage request object or result Show object if fibered
|
56
|
+
# @see http://services.tvrage.com/index.php?page=public&go=quickinfo TVRage Quickinfo API
|
57
|
+
# @see http://services.tvrage.com/tools/quickinfo.php?show=Chuck Chuck's Quickinfo
|
58
|
+
def by_name(name, options = {}, &block)
|
59
|
+
return Request.fibered(method(__method__), name, options) if defined? Fiber and Fiber.respond_to? :current and not block
|
60
|
+
raise ArgumentError, "No block given for completion callback" unless block
|
61
|
+
Request.new(Base_Uri, '/tools/quickinfo.php', block, :parse_element => 'pre', :show => name) do |request, xml|
|
62
|
+
options[:info] = parsed_quickinfo(xml)
|
63
|
+
Show.new(options[:info]['showid'], options) {|show| request.succeed show }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def parsed_quickinfo(raw_info)
|
68
|
+
info = Hash[raw_info.split(/\n/).collect {|line| k, v = line.split /@/; [k.gsub(' ', '').downcase, v] }]
|
69
|
+
info['showlink'] = info.delete('showurl')
|
70
|
+
info.each_key do |key|
|
71
|
+
case key.to_sym
|
72
|
+
when :latestepisode, :nextepisode
|
73
|
+
info[key] = Hash[[:number, :name, :date].zip(info[key].split /\^/)]
|
74
|
+
info[key][:date] = Date.parse(info[key][:date])
|
75
|
+
when :genres
|
76
|
+
info[key] = info[key].split ' | '
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
include Mapping
|
83
|
+
|
84
|
+
# @see EM:Sofa::Mapping
|
85
|
+
maps(
|
86
|
+
:ended => nil,
|
87
|
+
:showid => :show_id,
|
88
|
+
:showname => :name,
|
89
|
+
:name => nil,
|
90
|
+
:showlink => :show_link,
|
91
|
+
:seasons => nil,
|
92
|
+
:started => nil,
|
93
|
+
:startdate => :start_date,
|
94
|
+
:ended => nil,
|
95
|
+
:origin_country => nil,
|
96
|
+
:status => nil,
|
97
|
+
:classification => nil,
|
98
|
+
:runtime => :run_time,
|
99
|
+
:network => nil,
|
100
|
+
:airtime => :air_time,
|
101
|
+
:airday => :air_day,
|
102
|
+
:timezone => :time_zone,
|
103
|
+
:latestepisode => :latest_episode,
|
104
|
+
:nextepisode => :next_episode
|
105
|
+
)
|
106
|
+
maps(:genres => nil) #{ |value| value["genre"] }
|
107
|
+
maps(:akas => nil) { |value| value["aka"] }
|
108
|
+
|
109
|
+
# Maps :Episodelist to :season_list
|
110
|
+
# @see EM:Sofa::Mapping
|
111
|
+
# @yieldparam value [Hash, Array] A Hash of info if there's only one. An Array of info if there's multiple
|
112
|
+
# @yieldreturn [Array] A list of seasons initialized with value
|
113
|
+
maps(:Episodelist => :season_list) do |value|
|
114
|
+
case seasons = value["Season"]
|
115
|
+
when Hash
|
116
|
+
[Season.new(seasons)]
|
117
|
+
when Array
|
118
|
+
seasons.map { |info| Season.new(info) }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Stores all the info that was greedy-loaded
|
123
|
+
#
|
124
|
+
# @return [Hash] The full show info (including seasons and episodes)
|
125
|
+
# @see Show.full_info
|
126
|
+
attr_accessor :greedy
|
127
|
+
|
128
|
+
# Returns a new instance of Show, loading and then mapping info from the TVRage API.
|
129
|
+
#
|
130
|
+
# @param id [String] The show_id as per the TVRage API
|
131
|
+
# @option options [Boolean] :greedy Whether or not to eager load the Season and Episode info
|
132
|
+
# @param &block [Block] Called back with the show with parsed info unless fibered
|
133
|
+
def initialize(id, options = {}, &block)
|
134
|
+
raise RuntimeError.new("id is required") unless (@show_id = id)
|
135
|
+
return TVRage::Request.fibered(method(__method__), id, options) if defined? Fiber and Fiber.respond_to? :current and not block
|
136
|
+
raise ArgumentError, "No block given for completion callback" unless block
|
137
|
+
klass = self.class
|
138
|
+
if options[:greedy]
|
139
|
+
return block.call(self) if @greedy
|
140
|
+
klass.full_info(@show_id) do |full_info|
|
141
|
+
next block.call(nil) unless full_info
|
142
|
+
update_with_mapping(@greedy = full_info)
|
143
|
+
block.call(self)
|
144
|
+
end
|
145
|
+
elsif options[:info]
|
146
|
+
update_with_mapping(options[:info])
|
147
|
+
block.call(self)
|
148
|
+
else
|
149
|
+
klass.info(@show_id) do |info|
|
150
|
+
next block.call(nil) unless info
|
151
|
+
update_with_mapping(info)
|
152
|
+
block.call(self)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# @param &block [Block] Called back with the list of seasons
|
158
|
+
def season_list(&block)
|
159
|
+
if defined? Fiber and Fiber.respond_to? :current and not block
|
160
|
+
f = Fiber.current
|
161
|
+
method(__method__).call {|data| f.resume(data) }
|
162
|
+
return Fiber.yield
|
163
|
+
end
|
164
|
+
raise ArgumentError, "No block given for completion callback" unless block
|
165
|
+
puts "@season_list = #@season_list" if @season_list
|
166
|
+
return block.call(@season_list) if @season_list
|
167
|
+
self.class.episode_list(@show_id) do |episode_list|
|
168
|
+
update_with_mapping(episode_list)
|
169
|
+
block.call(@season_list)
|
170
|
+
end
|
171
|
+
true
|
172
|
+
end
|
173
|
+
|
174
|
+
# @param &block [Block] Called back with the list of episodes
|
175
|
+
def episode_list(&block)
|
176
|
+
if defined? Fiber and Fiber.respond_to? :current and not block
|
177
|
+
f = Fiber.current
|
178
|
+
method(__method__).call {|data| f.resume(data) }
|
179
|
+
return Fiber.yield
|
180
|
+
end
|
181
|
+
raise ArgumentError, "No block given for completion callback" unless block
|
182
|
+
season_list do |seasons|
|
183
|
+
block.call(seasons.collect { |season| season.episodes }.flatten)
|
184
|
+
end
|
185
|
+
true
|
186
|
+
end
|
187
|
+
|
188
|
+
class NotFound < RuntimeError
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -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>
|