howcast 0.7.4 → 0.7.15
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/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +38 -0
- data/{README.markdown → README.md} +44 -13
- data/Rakefile +6 -39
- data/VERSION +1 -1
- data/fixtures/categories.xml +2230 -0
- data/fixtures/category.1585.xml +24 -0
- data/fixtures/homepage.staff_videos.xml +315 -0
- data/fixtures/invalid.api_key.xml +6 -0
- data/fixtures/playlist.4566.xml +484 -0
- data/fixtures/users.someone.profile.videos.xml +440 -0
- data/fixtures/video.233.generated.xml +1563 -0
- data/fixtures/video.233.xml +830 -0
- data/howcast.gemspec +31 -90
- data/lib/howcast.rb +1 -1
- data/lib/howcast/client.rb +1 -1
- data/lib/howcast/client/base.rb +232 -188
- data/lib/howcast/client/category.rb +31 -13
- data/lib/howcast/client/homepage.rb +10 -8
- data/lib/howcast/client/marker.rb +2 -0
- data/lib/howcast/client/playlist.rb +2 -0
- data/lib/howcast/client/search.rb +11 -11
- data/lib/howcast/client/type.rb +48 -0
- data/lib/howcast/client/user.rb +2 -0
- data/lib/howcast/client/utils.rb +53 -0
- data/lib/howcast/client/video.rb +39 -25
- data/lib/howcast/ext/string.rb +8 -0
- data/lib/howcast/hpricot/elements.rb +22 -0
- data/lib/howcast/version.rb +3 -0
- data/script/github-test.rb +24 -0
- data/spec/howcast/client/base_spec.rb +2 -2
- data/spec/howcast/client/category_spec.rb +41 -2
- data/spec/howcast/client/homepage_spec.rb +8 -8
- data/spec/howcast/client/playlist_spec.rb +6 -4
- data/spec/howcast/client/search_spec.rb +7 -8
- data/spec/howcast/client/user_spec.rb +9 -7
- data/spec/howcast/client/video_spec.rb +106 -22
- data/spec/spec_helper.rb +4 -7
- data/spec/xml_fixtures_helper.rb +20 -2895
- metadata +94 -28
- data/CHANGELOG +0 -108
- data/Manifest +0 -19
- data/howcast-0.7.3.gem +0 -0
- data/spec/string_matchers_helper.rb +0 -22
data/howcast.gemspec
CHANGED
@@ -1,97 +1,38 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "howcast/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
9
|
-
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
6
|
+
s.name = "howcast"
|
7
|
+
s.version = Howcast::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Jingshen Jimmy Zhang", "Ian Smith-Heisters", "Juris Galang"]
|
10
|
+
s.email = ["support@howcast.com"]
|
11
|
+
s.homepage = "http://api.howcast.com/"
|
12
|
+
s.summary = %q{Ruby-bindings for the Howcast API}
|
13
13
|
s.description = %q{ Howcast offers an Application Programming Interface (API) which allows
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
}
|
23
|
-
s.email = %q{support@howcast.com}
|
24
|
-
s.extra_rdoc_files = [
|
25
|
-
"README.markdown"
|
26
|
-
]
|
27
|
-
s.files = [
|
28
|
-
"CHANGELOG",
|
29
|
-
"License.txt",
|
30
|
-
"Manifest",
|
31
|
-
"README.markdown",
|
32
|
-
"Rakefile",
|
33
|
-
"VERSION",
|
34
|
-
"howcast-0.7.3.gem",
|
35
|
-
"howcast.gemspec",
|
36
|
-
"lib/howcast.rb",
|
37
|
-
"lib/howcast/client.rb",
|
38
|
-
"lib/howcast/client/base.rb",
|
39
|
-
"lib/howcast/client/category.rb",
|
40
|
-
"lib/howcast/client/homepage.rb",
|
41
|
-
"lib/howcast/client/marker.rb",
|
42
|
-
"lib/howcast/client/playlist.rb",
|
43
|
-
"lib/howcast/client/search.rb",
|
44
|
-
"lib/howcast/client/user.rb",
|
45
|
-
"lib/howcast/client/video.rb",
|
46
|
-
"lib/howcast/errors.rb",
|
47
|
-
"lib/howcast/logging.rb",
|
48
|
-
"spec/howcast/client/base_spec.rb",
|
49
|
-
"spec/howcast/client/category_spec.rb",
|
50
|
-
"spec/howcast/client/homepage_spec.rb",
|
51
|
-
"spec/howcast/client/playlist_spec.rb",
|
52
|
-
"spec/howcast/client/search_spec.rb",
|
53
|
-
"spec/howcast/client/user_spec.rb",
|
54
|
-
"spec/howcast/client/video_spec.rb",
|
55
|
-
"spec/output_capture_helper.rb",
|
56
|
-
"spec/spec.opts",
|
57
|
-
"spec/spec_helper.rb",
|
58
|
-
"spec/string_matchers_helper.rb",
|
59
|
-
"spec/xml_fixtures_helper.rb",
|
60
|
-
"tasks/github.rake"
|
61
|
-
]
|
62
|
-
s.homepage = %q{http://github.com/howcast/howcast-gem}
|
63
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
64
|
-
s.require_paths = ["lib"]
|
65
|
-
s.rubygems_version = %q{1.3.6}
|
66
|
-
s.summary = %q{Howcast API Ruby Wrapper}
|
67
|
-
s.test_files = [
|
68
|
-
"spec/howcast/client/base_spec.rb",
|
69
|
-
"spec/howcast/client/category_spec.rb",
|
70
|
-
"spec/howcast/client/homepage_spec.rb",
|
71
|
-
"spec/howcast/client/playlist_spec.rb",
|
72
|
-
"spec/howcast/client/search_spec.rb",
|
73
|
-
"spec/howcast/client/user_spec.rb",
|
74
|
-
"spec/howcast/client/video_spec.rb",
|
75
|
-
"spec/output_capture_helper.rb",
|
76
|
-
"spec/spec_helper.rb",
|
77
|
-
"spec/string_matchers_helper.rb",
|
78
|
-
"spec/xml_fixtures_helper.rb"
|
79
|
-
]
|
14
|
+
developers to build applications that interface with Howcast. The Howcast
|
15
|
+
API is RESTful (REpresentational State Transfer) and users of this API will
|
16
|
+
be able: 1) Retreive detailed information about a single video, including
|
17
|
+
metadata such as title, description, video views, rating etc; 2) Retrieve a
|
18
|
+
list of videos restricted by a set of filters offered by Howcast and sorted
|
19
|
+
using several metrics that you can specify (most recent, most views, etc);
|
20
|
+
3) Search for video; 4) And much more. Note: Before you can use our APIs,
|
21
|
+
you must register an API key, that is submitted with each request.
|
22
|
+
}
|
80
23
|
|
81
|
-
|
82
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
83
|
-
s.specification_version = 3
|
24
|
+
s.rubyforge_project = "howcast"
|
84
25
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
26
|
+
s.files = `git ls-files`.split("\n")
|
27
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
28
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
29
|
+
s.require_paths = ["lib"]
|
30
|
+
|
31
|
+
s.add_runtime_dependency(%q<hpricot>, [">= 0"])
|
32
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
|
33
|
+
|
34
|
+
#s.add_development_dependency(%q<jeweler>, [">= 0"])
|
35
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
36
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
37
|
+
s.add_development_dependency(%q<ruby-debug>, [">= 0"])
|
96
38
|
end
|
97
|
-
|
data/lib/howcast.rb
CHANGED
data/lib/howcast/client.rb
CHANGED
@@ -2,6 +2,6 @@
|
|
2
2
|
class Howcast::Client
|
3
3
|
end
|
4
4
|
|
5
|
-
%w(client/base client/video client/search client/category client/marker client/user client/homepage client/playlist).each do |dependency|
|
5
|
+
%w(client/utils client/base client/video client/search client/category client/marker client/user client/homepage client/playlist client/type).each do |dependency|
|
6
6
|
require(File.expand_path(File.join(File.dirname(__FILE__), dependency)))
|
7
7
|
end
|
data/lib/howcast/client/base.rb
CHANGED
@@ -22,10 +22,16 @@
|
|
22
22
|
#++
|
23
23
|
|
24
24
|
require 'rubygems'
|
25
|
+
require 'benchmark'
|
26
|
+
require 'timeout'
|
25
27
|
require 'hpricot'
|
28
|
+
require 'nokogiri'
|
26
29
|
require 'open-uri'
|
27
30
|
require 'uri'
|
28
31
|
|
32
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../hpricot/elements'))
|
33
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../ext/string'))
|
34
|
+
|
29
35
|
class Howcast::Client
|
30
36
|
attr_accessor :key
|
31
37
|
|
@@ -56,210 +62,248 @@ class Howcast::Client
|
|
56
62
|
end
|
57
63
|
|
58
64
|
def base_uri
|
59
|
-
@base_uri ||= URI.parse("http://
|
65
|
+
@base_uri ||= URI.parse("http://api.howcast.com")
|
60
66
|
end
|
61
67
|
end
|
68
|
+
|
62
69
|
protected
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
70
|
+
# Establishes a connection with the Howcast API. Will auto append the api key, that was used
|
71
|
+
# to instantiate the Client object, to the URL
|
72
|
+
#
|
73
|
+
# === Inputs
|
74
|
+
#
|
75
|
+
# * <tt>relative_path</tt> -- should be the path after <tt>http://www.howcast.com/</tt>
|
76
|
+
#
|
77
|
+
# === Outputs
|
78
|
+
#
|
79
|
+
# Hpricot object encapsulating the xml returned from the Howcast API
|
80
|
+
#
|
81
|
+
# === Exceptions
|
82
|
+
#
|
83
|
+
# * <tt>Howcast::ApiNotFound</tt> -- raised if the requested +relative_path+ is malformed or not available (404)
|
84
|
+
# * <tt>Howcast::ApiKeyNotFound</tt> -- raised if the +api_key+ is invalid
|
85
|
+
#
|
86
|
+
# === Examples
|
87
|
+
#
|
88
|
+
# Get the Hpricot data for most recent howcast studios videos
|
89
|
+
# establish_connection("videos/most_recent/howcast_studios.xml")
|
90
|
+
def establish_connection(relative_path_and_query)
|
91
|
+
begin
|
92
|
+
uri = self.class.base_uri.dup
|
93
|
+
relative_path_and_query = '/' + relative_path_and_query unless relative_path_and_query[0] == '/'
|
94
|
+
uri.path, uri.query = *relative_path_and_query.split('?')
|
95
|
+
|
96
|
+
doc = nil
|
97
|
+
time = Benchmark.realtime do
|
98
|
+
doc = Hpricot.XML open(attach_api_key uri)
|
99
|
+
end
|
100
|
+
Howcast.log.info "Established connection with: '#{uri.to_s}' after #{time * 1000}ms"
|
101
|
+
|
102
|
+
raise Howcast::ApiKeyNotFound \
|
103
|
+
if doc.at(:err) && doc.at(:err)['msg'].match(/Invalid API Key/)
|
104
|
+
|
105
|
+
doc
|
106
|
+
rescue Timeout::Error
|
107
|
+
raise Howcast::ApiError, "Timed-out after #{time * 1000}ms while attempting to access the API at #{uri.to_s}"
|
91
108
|
rescue URI::InvalidURIError
|
92
|
-
raise Howcast::ApiNotFound
|
93
|
-
rescue OpenURI::HTTPError =>
|
94
|
-
raise Howcast::ApiError
|
109
|
+
raise Howcast::ApiNotFound, "Invalid URL #{uri.to_s} requested."
|
110
|
+
rescue OpenURI::HTTPError => e
|
111
|
+
raise Howcast::ApiError, "HTTP error #{e.message} accessing the API at #{uri.to_s}."
|
95
112
|
end
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
113
|
+
end
|
114
|
+
|
115
|
+
# Parses the xml for a single item from +xml+ and creates a new +klass+ object
|
116
|
+
#
|
117
|
+
# === Inputs
|
118
|
+
#
|
119
|
+
# * <tt>xml</tt> -- See below for a sample xml input
|
120
|
+
# * <tt>klass</tt> -- Class to create - Video | Category supported
|
121
|
+
#
|
122
|
+
# Sample input xml
|
123
|
+
# <video>
|
124
|
+
# <id>1086</id>
|
125
|
+
# <rating>96</rating>
|
126
|
+
# <title>How To Choose a Paintbrush</title>
|
127
|
+
# <category-id>19</category-id>
|
128
|
+
# <description>
|
129
|
+
# <![CDATA[Yes, you could just use your fingers, but selecting the best brushes for your painting might achieve a slightly more grown-up result.]]>
|
130
|
+
# </description>
|
131
|
+
# <views>362</views>
|
132
|
+
# <permalink>http://www.howcast.com/guides/1086-How-To-Choose-a-Paintbrush</permalink>
|
133
|
+
# <username>michaelrsanchez</username>
|
134
|
+
# <created-at>Thu, 20 Dec 2007 14:14:58 -0800</created-at>
|
135
|
+
# </video>
|
136
|
+
#
|
137
|
+
# === Outputs
|
138
|
+
#
|
139
|
+
# +klass+ object with initialized attributes
|
140
|
+
def parse_single_xml(xml, klass)
|
141
|
+
hash = { }
|
142
|
+
klass.attr_accessors.each do |attribute|
|
143
|
+
node_name = attribute.to_s.gsub("_", "-") # xml schema uses hyphens for spaces, but ruby uses underscores
|
144
|
+
if node_name == "category-hierarchy"
|
145
|
+
hash[attribute] = category_hierarchy_for(xml) unless xml.at(node_name).nil?
|
146
|
+
elsif node_name == "playlist-memberships"
|
147
|
+
hash[attribute] = playlist_memberships_for(xml) unless xml.at(node_name).nil?
|
148
|
+
elsif node_name == "ingredients"
|
149
|
+
hash[attribute] = ingredients_for(xml) unless xml.at(node_name).nil?
|
150
|
+
elsif node_name == "markers"
|
151
|
+
hash[attribute] = markers_for(xml) unless xml.at(node_name).nil?
|
152
|
+
elsif node_name == "related-videos"
|
153
|
+
hash[attribute] = related_videos_for(xml) unless xml.at(node_name).nil?
|
154
|
+
elsif node_name == "videos"
|
155
|
+
hash[attribute] = videos_for(xml) unless xml.at(node_name).nil?
|
156
|
+
elsif node_name == "playlist-thumbnail-url"
|
157
|
+
# TODO: Resolve this hack, xml attributes aren't named consistently
|
158
|
+
hash[attribute] = !xml.at(node_name).nil? ? xml.at(node_name).inner_text.strip : xml.at("thumbnail-url").inner_text.strip
|
159
|
+
elsif node_name == "type"
|
160
|
+
hash[attribute] = type_for(xml) unless xml.at(node_name).nil?
|
161
|
+
elsif %w{ ads-allowed mature-content }.include? node_name
|
162
|
+
hash[attribute] = !xml.at(node_name).nil? ? "true" : ""
|
163
|
+
else
|
164
|
+
hash[attribute] = !xml.at(node_name).nil? ? xml.at(node_name).inner_text.strip : ""
|
142
165
|
end
|
143
|
-
hash.values.all?{|v| v==""} ? nil : klass.new(hash)
|
144
|
-
end
|
145
|
-
|
146
|
-
# Creates parameters to append to a uri
|
147
|
-
#
|
148
|
-
# === Inputs
|
149
|
-
#
|
150
|
-
# Options are:
|
151
|
-
# * <tt>:page</tt> -- the page number
|
152
|
-
# * <tt>:use_ampersand</tt> -- boolean to return ampersand (defaults to false)
|
153
|
-
#
|
154
|
-
# === Outputs
|
155
|
-
#
|
156
|
-
# A valid suffix string to append to the end of a url
|
157
|
-
#
|
158
|
-
# === Examples
|
159
|
-
#
|
160
|
-
# "?page=2"
|
161
|
-
# uri_suffix(:page => 2)
|
162
|
-
# "&page=2"
|
163
|
-
# uri_suffix(:page => 3, :use_ampersand => true)
|
164
|
-
def uri_suffix(opts)
|
165
|
-
opts && opts[:page] ? "#{opts[:use_ampersand] ? '&' : '?'}page=#{opts[:page]}" : ""
|
166
166
|
end
|
167
|
+
hash.values.all?{ |v| (v == "") or (v.respond_to?(:empty?) and v.empty?) } ? nil : klass.new(hash)
|
168
|
+
end
|
167
169
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
170
|
+
# Creates parameters to append to a uri
|
171
|
+
#
|
172
|
+
# === Inputs
|
173
|
+
#
|
174
|
+
# Options are:
|
175
|
+
# * <tt>:page</tt> -- the page number
|
176
|
+
# * <tt>:use_ampersand</tt> -- boolean to return ampersand (defaults to false)
|
177
|
+
#
|
178
|
+
# === Outputs
|
179
|
+
#
|
180
|
+
# A valid suffix string to append to the end of a url
|
181
|
+
#
|
182
|
+
# === Examples
|
183
|
+
#
|
184
|
+
# "?page=2"
|
185
|
+
# uri_suffix(:page => 2)
|
186
|
+
# "&page=2"
|
187
|
+
# uri_suffix(:page => 3, :use_ampersand => true)
|
188
|
+
def uri_suffix(opts)
|
189
|
+
opts && opts[:page] ? "#{opts[:use_ampersand] ? '&' : '?'}page=#{opts[:page]}" : ""
|
190
|
+
end
|
191
|
+
|
192
|
+
# Appends the api key to a uri and returns the appended uri
|
193
|
+
#
|
194
|
+
# === Inputs
|
195
|
+
#
|
196
|
+
# * <tt>uri</tt> -- the URI object to append the api_key to
|
197
|
+
#
|
198
|
+
# === Outputs
|
199
|
+
#
|
200
|
+
# The uri with the api_key appended to the query string
|
201
|
+
#
|
202
|
+
# === Examples
|
203
|
+
#
|
204
|
+
# attach_api_key(URI.parse("http://www.howcast.com")).to_s
|
205
|
+
# => "http://www.howcast.com?api_key=APIKEYHERE"
|
206
|
+
#
|
207
|
+
# attach_api_key(URI.parse("http://www.howcast.com/videos/most_recent/all?page=2")).to_s
|
208
|
+
# => "http://www.howcast.com/videos/most_recent/all?page=2&api_key=APIKEYHERE"
|
209
|
+
def attach_api_key(uri)
|
210
|
+
uri = uri.dup
|
211
|
+
key = "api_key=#{self.key}"
|
212
|
+
uri.query = uri.query.to_s.strip != "" ? uri.query+"&"+key : key
|
213
|
+
uri
|
214
|
+
end
|
191
215
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
216
|
+
# From merb/core_ext/hash.rb, line 87
|
217
|
+
def hash_to_params hash
|
218
|
+
params = ''
|
219
|
+
stack = []
|
196
220
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
221
|
+
hash.keys.sort{ |a, b| a.to_s <=> b.to_s }.each do |k|
|
222
|
+
v = hash[k]
|
223
|
+
if v.is_a?(Hash)
|
224
|
+
stack << [k,v]
|
225
|
+
else
|
226
|
+
params << "#{k}=#{v}&"
|
203
227
|
end
|
228
|
+
end
|
204
229
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
end
|
230
|
+
stack.each do |parent, h|
|
231
|
+
h.each do |k, v|
|
232
|
+
if v.is_a?(Hash)
|
233
|
+
stack << ["#{parent}[#{k}]", v]
|
234
|
+
else
|
235
|
+
params << "#{parent}[#{k}]=#{v}&"
|
212
236
|
end
|
213
237
|
end
|
214
|
-
|
215
|
-
params.chop! # trailing &
|
216
|
-
params
|
217
238
|
end
|
239
|
+
|
240
|
+
params.chop! # trailing &
|
241
|
+
params
|
242
|
+
end
|
218
243
|
|
219
244
|
private
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
245
|
+
def category_hierarchy_for(xml)
|
246
|
+
categories = []
|
247
|
+
node = xml.at('category-hierarchy')
|
248
|
+
node.children_of_type('category').each do |child|
|
249
|
+
category = Category.new(:id => child['id'], :parent_id => child['parent_id'], :name => child.inner_text, :permalink => child['permalink'])
|
250
|
+
categories << category
|
251
|
+
end unless node.nil?
|
252
|
+
categories
|
253
|
+
end
|
254
|
+
|
255
|
+
def playlist_memberships_for(xml)
|
256
|
+
memberships = []
|
257
|
+
node = xml.at('playlist-memberships')
|
258
|
+
node.children_of_type('playlist').each do |child|
|
259
|
+
playlist = Playlist.new(:id => child['id'], :title => child.inner_text)
|
260
|
+
memberships << playlist
|
261
|
+
end unless node.nil?
|
262
|
+
memberships
|
263
|
+
end
|
264
|
+
|
265
|
+
def ingredients_for(xml)
|
266
|
+
ingredients = []
|
267
|
+
node = xml.at('ingredients')
|
268
|
+
node.children_of_type('ingredient').each do |child|
|
269
|
+
ingredients << child.inner_text.strip
|
270
|
+
end unless node.nil?
|
271
|
+
ingredients
|
272
|
+
end
|
273
|
+
|
274
|
+
def markers_for(xml)
|
275
|
+
markers = []
|
276
|
+
node = xml.at('markers')
|
277
|
+
node.children_of_type('marker').each do |child|
|
278
|
+
markers << parse_single_xml(child, Marker)
|
279
|
+
end unless node.nil?
|
280
|
+
markers
|
281
|
+
end
|
282
|
+
|
283
|
+
def type_for(xml)
|
284
|
+
node = xml.at('type')
|
285
|
+
if node['status'] && node['class']
|
286
|
+
Type.new(:name => node.inner_text.strip, :kind => node['class'], :status => node['status'])
|
287
|
+
else
|
288
|
+
node.inner_text.strip
|
264
289
|
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def related_videos_for(xml)
|
293
|
+
related = []
|
294
|
+
node = xml.at('related-videos')
|
295
|
+
node.children_of_type('video').each do |child|
|
296
|
+
related << parse_single_xml(child, Video)
|
297
|
+
end unless node.nil?
|
298
|
+
related
|
299
|
+
end
|
300
|
+
|
301
|
+
def videos_for(xml)
|
302
|
+
videos = []
|
303
|
+
node = xml.at('videos')
|
304
|
+
node.children_of_type('video').each do |child|
|
305
|
+
videos << parse_single_xml(child, Video)
|
306
|
+
end unless node.nil?
|
307
|
+
videos
|
308
|
+
end
|
265
309
|
end
|