howcast 0.4.12 → 0.4.13
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/CHANGELOG +4 -0
- data/VERSION +1 -1
- data/howcast.gemspec +11 -10
- data/lib/howcast/client.rb +1 -1
- data/lib/howcast/client/base.rb +53 -4
- data/lib/howcast/client/marker.rb +46 -0
- data/lib/howcast/client/video.rb +2 -1
- data/lib/howcast/errors.rb +3 -8
- data/spec/howcast/client/video_spec.rb +41 -0
- data/spec/output_capture_helper.rb +1 -1
- data/spec/xml_fixtures_helper.rb +135 -44
- metadata +9 -8
data/CHANGELOG
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.13
|
data/howcast.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{howcast}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.13"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jingshen Jimmy Zhang", "Ian Smith-Heisters"]
|
12
|
-
s.date = %q{2010-03-
|
12
|
+
s.date = %q{2010-03-08}
|
13
13
|
s.description = %q{ Howcast offers an Application Programming Interface (API) which allows
|
14
14
|
developers to build applications that interface with Howcast. The Howcast
|
15
15
|
API is RESTful (REpresentational State Transfer) and users of this API will
|
@@ -36,6 +36,7 @@ Gem::Specification.new do |s|
|
|
36
36
|
"lib/howcast/client.rb",
|
37
37
|
"lib/howcast/client/base.rb",
|
38
38
|
"lib/howcast/client/category.rb",
|
39
|
+
"lib/howcast/client/marker.rb",
|
39
40
|
"lib/howcast/client/search.rb",
|
40
41
|
"lib/howcast/client/video.rb",
|
41
42
|
"lib/howcast/errors.rb",
|
@@ -54,17 +55,17 @@ Gem::Specification.new do |s|
|
|
54
55
|
s.homepage = %q{http://github.com/howcast/howcast-gem}
|
55
56
|
s.rdoc_options = ["--charset=UTF-8"]
|
56
57
|
s.require_paths = ["lib"]
|
57
|
-
s.rubygems_version = %q{1.3.
|
58
|
+
s.rubygems_version = %q{1.3.4}
|
58
59
|
s.summary = %q{Howcast API Ruby Wrapper}
|
59
60
|
s.test_files = [
|
60
|
-
"spec/
|
61
|
-
"spec/xml_fixtures_helper.rb",
|
62
|
-
"spec/string_matchers_helper.rb",
|
63
|
-
"spec/spec_helper.rb",
|
64
|
-
"spec/howcast/client/base_spec.rb",
|
65
|
-
"spec/howcast/client/video_spec.rb",
|
61
|
+
"spec/howcast/client/base_spec.rb",
|
66
62
|
"spec/howcast/client/category_spec.rb",
|
67
|
-
"spec/howcast/client/search_spec.rb"
|
63
|
+
"spec/howcast/client/search_spec.rb",
|
64
|
+
"spec/howcast/client/video_spec.rb",
|
65
|
+
"spec/output_capture_helper.rb",
|
66
|
+
"spec/spec_helper.rb",
|
67
|
+
"spec/string_matchers_helper.rb",
|
68
|
+
"spec/xml_fixtures_helper.rb"
|
68
69
|
]
|
69
70
|
|
70
71
|
if s.respond_to? :specification_version then
|
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).each do |dependency|
|
5
|
+
%w(client/base client/video client/search client/category client/marker).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
@@ -88,8 +88,10 @@ class Howcast::Client
|
|
88
88
|
Howcast.log.info "Established connection with: '#{url}'"
|
89
89
|
raise Howcast::ApiKeyNotFound if h.at(:error) && h.at(:error).inner_html.match(/Invalid API Key/)
|
90
90
|
return h
|
91
|
-
rescue URI::InvalidURIError
|
92
|
-
raise Howcast::ApiNotFound.new("Invalid URL requested. Refer to the Howcast API for supported URL's")
|
91
|
+
rescue URI::InvalidURIError
|
92
|
+
raise Howcast::ApiNotFound.new("Invalid URL #{url.inspect} requested. Refer to the Howcast API for supported URL's")
|
93
|
+
rescue OpenURI::HTTPError => boom
|
94
|
+
raise Howcast::ApiError.new("HTTP error #{boom.message} accessing the API. Refer to the Howcast API for supported URL's")
|
93
95
|
end
|
94
96
|
|
95
97
|
# Parses the xml for a single item from +xml+ and creates a new +klass+ object
|
@@ -121,7 +123,17 @@ class Howcast::Client
|
|
121
123
|
hash = {}
|
122
124
|
klass.attr_accessors.each do |attribute|
|
123
125
|
node_name = attribute.to_s.gsub("_", "-") # xml schema uses hyphens for spaces, but ruby uses underscores
|
124
|
-
|
126
|
+
if node_name == "category-hierarchy"
|
127
|
+
hash[attribute] = category_hierarchy_for(xml) unless xml.at(node_name).nil?
|
128
|
+
elsif node_name == "ingredients"
|
129
|
+
hash[attribute] = ingredients_for(xml) unless xml.at(node_name).nil?
|
130
|
+
elsif node_name == "markers"
|
131
|
+
hash[attribute] = markers_for(xml) unless xml.at(node_name).nil?
|
132
|
+
elsif node_name == "related-videos"
|
133
|
+
hash[attribute] = related_videos_for(xml) unless xml.at(node_name).nil?
|
134
|
+
else
|
135
|
+
hash[attribute] = !xml.at(node_name).nil? ? xml.at(node_name).inner_text.strip : ""
|
136
|
+
end
|
125
137
|
end
|
126
138
|
hash.values.all?{|v| v==""} ? nil : klass.new(hash)
|
127
139
|
end
|
@@ -198,5 +210,42 @@ class Howcast::Client
|
|
198
210
|
params.chop! # trailing &
|
199
211
|
params
|
200
212
|
end
|
213
|
+
|
214
|
+
private
|
215
|
+
def category_hierarchy_for(xml)
|
216
|
+
categories = []
|
217
|
+
node = xml.at('category-hierarchy')
|
218
|
+
node.children_of_type('category').each do |child|
|
219
|
+
category = Category.new(:id => child['id'], :parent_id => child['parent_id'], :name => child.inner_text)
|
220
|
+
categories << category
|
221
|
+
end unless node.nil?
|
222
|
+
categories
|
223
|
+
end
|
224
|
+
|
225
|
+
def ingredients_for(xml)
|
226
|
+
ingredients = []
|
227
|
+
node = xml.at('ingredients')
|
228
|
+
node.children_of_type('ingredient').each do |child|
|
229
|
+
ingredients << child.inner_text.strip
|
230
|
+
end unless node.nil?
|
231
|
+
ingredients
|
232
|
+
end
|
233
|
+
|
234
|
+
def markers_for(xml)
|
235
|
+
markers = []
|
236
|
+
node = xml.at('markers')
|
237
|
+
node.children_of_type('marker').each do |child|
|
238
|
+
markers << parse_single_xml(child, Marker)
|
239
|
+
end unless node.nil?
|
240
|
+
markers
|
241
|
+
end
|
242
|
+
|
243
|
+
def related_videos_for(xml)
|
244
|
+
related = []
|
245
|
+
node = xml.at('related-videos')
|
246
|
+
node.children_of_type('video').each do |child|
|
247
|
+
related << parse_single_xml(child, Video)
|
248
|
+
end unless node.nil?
|
249
|
+
related
|
250
|
+
end
|
201
251
|
end
|
202
|
-
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 Howcast Media Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
class Howcast::Client
|
25
|
+
class Marker
|
26
|
+
extend WatchAttrAccessors
|
27
|
+
attr_accessor :id, :position, :timemarker, :type, :thumbnail_url, :title, :textile_text, :text
|
28
|
+
|
29
|
+
# Creates a new Marker object which is used to encapsulate all the attributes available
|
30
|
+
# from the Howcast Video API.
|
31
|
+
#
|
32
|
+
# === Inputs
|
33
|
+
#
|
34
|
+
# * <tt>attributes</tt> -- A hash to set the various attributes of the marker object
|
35
|
+
#
|
36
|
+
# === Examples
|
37
|
+
#
|
38
|
+
# Initialize a marker with title "Do something"
|
39
|
+
# Marker.new :title => "Do something"
|
40
|
+
def initialize(attributes={})
|
41
|
+
attributes.each do |k, v|
|
42
|
+
self.send("#{k}=", v) if self.respond_to?(k)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/howcast/client/video.rb
CHANGED
@@ -38,7 +38,8 @@ class Howcast::Client
|
|
38
38
|
extend WatchAttrAccessors
|
39
39
|
attr_accessor :id, :title, :permalink, :thumbnail_url, :category_id,
|
40
40
|
:views, :username, :duration, :created_at, :rating, :description, :width, :height,
|
41
|
-
:badges, :easy_steps, :embed
|
41
|
+
:badges, :easy_steps, :embed, :category_hierarchy, :ingredients, :markers, :related_videos
|
42
|
+
|
42
43
|
# Creates a new Video object which is used to encapsulate all the attributes available
|
43
44
|
# from the Howcast Video API
|
44
45
|
#
|
data/lib/howcast/errors.rb
CHANGED
@@ -67,6 +67,47 @@ describe Howcast::Client, "video" do
|
|
67
67
|
it "should set the permalink attribute in the video model response" do
|
68
68
|
@hc.video(2).permalink.should == "http://www.howcast.com/videos/233-How-To-Do-a-Noble-Pose"
|
69
69
|
end
|
70
|
+
|
71
|
+
it "should set the category hierarchy in the video model response" do
|
72
|
+
hierarchy = @hc.video(2).category_hierarchy
|
73
|
+
hierarchy.size.should == 3
|
74
|
+
hierarchy.first.instance_of?(Howcast::Client::Category).should be_true
|
75
|
+
hierarchy[0].name.should == "Health & Nutrition"
|
76
|
+
hierarchy[1].name.should == "Exercise"
|
77
|
+
hierarchy[2].name.should == "Yoga"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should set the ingredients in the video model response" do
|
81
|
+
ingredients = @hc.video(2).ingredients
|
82
|
+
ingredients.size.should == 4
|
83
|
+
ingredients[0].should == "Comfortable clothing suitable for stretching and moving"
|
84
|
+
ingredients[1].should == "A calm place where you won't be distracted or disturbed"
|
85
|
+
ingredients[2].should == "A yoga mat or folded blanket"
|
86
|
+
ingredients[3].should == "A belt or strap"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should set the markers in the video model response" do
|
90
|
+
markers = @hc.video(2).markers
|
91
|
+
markers.size.should == 4
|
92
|
+
markers.first.instance_of?(Howcast::Client::Marker).should be_true
|
93
|
+
markers[0].type.should == "Step"
|
94
|
+
markers[0].textile_text.should == "Sit down on the mat with your legs straight out in front of you."
|
95
|
+
markers[1].type.should == "Tip"
|
96
|
+
markers[1].textile_text.should == "It's okay to slightly bend at the knees while extending into this pose."
|
97
|
+
markers[2].type.should == "Step"
|
98
|
+
markers[2].textile_text.should == "To release the pose, inhale, and raise your torso straight up with your arms stretched overhead, then exhale and lower your hands to the floor. Now to conquer kickball..."
|
99
|
+
markers[3].type.should == "Fact"
|
100
|
+
markers[3].textile_text.should == "Pop nobility Sting recently admitted that he and his wife's claims of yoga-inspired marathons of tantric sex was all a joke, saying, \"I have frantic sex, not tantric sex.\""
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should set the related videos in the video model response" do
|
104
|
+
related = @hc.video(2).related_videos
|
105
|
+
related.size.should == 2
|
106
|
+
related.first.instance_of?(Howcast::Client::Video).should be_true
|
107
|
+
related[0].title.should == "How To Do the Extended Triangle Pose"
|
108
|
+
related[0].category_hierarchy.last.name.should == "Yoga"
|
109
|
+
related[1].title.should == "How To Do a Seated Spinal Twist Pose"
|
110
|
+
end
|
70
111
|
end
|
71
112
|
|
72
113
|
describe Howcast::Client, "videos" do
|
data/spec/xml_fixtures_helper.rb
CHANGED
@@ -81,6 +81,11 @@ module XmlFixturesHelper
|
|
81
81
|
<category-id>2</category-id>
|
82
82
|
<duration>22</duration>
|
83
83
|
<id>233</id>
|
84
|
+
<category-hierarchy>
|
85
|
+
<category id="479">Health & Nutrition</category>
|
86
|
+
<category parent_id="479" id="510">Exercise</category>
|
87
|
+
<category parent_id="510" id="515">Yoga</category>
|
88
|
+
</category-hierarchy>
|
84
89
|
<easy-steps>true</easy-steps>
|
85
90
|
<badges>Howcast Studios</badges>
|
86
91
|
<title>How To Do a Noble Pose</title>
|
@@ -96,55 +101,141 @@ module XmlFixturesHelper
|
|
96
101
|
<views>38</views>
|
97
102
|
<rating>2.0</rating>
|
98
103
|
<created-at>#{Time.now.rfc822}</created-at>
|
104
|
+
<ingredients>
|
105
|
+
<ingredient>
|
106
|
+
<![CDATA[Comfortable clothing suitable for stretching and moving]]>
|
107
|
+
</ingredient>
|
108
|
+
<ingredient>
|
109
|
+
<![CDATA[A calm place where you won't be distracted or disturbed]]>
|
110
|
+
</ingredient>
|
111
|
+
<ingredient>
|
112
|
+
<![CDATA[A yoga mat or folded blanket]]>
|
113
|
+
</ingredient>
|
114
|
+
<ingredient>
|
115
|
+
<![CDATA[A belt or strap]]>
|
116
|
+
</ingredient>
|
117
|
+
</ingredients>
|
118
|
+
<markers>
|
119
|
+
<marker>
|
120
|
+
<id>3716</id>
|
121
|
+
<position>1</position>
|
122
|
+
<timemarker>32</timemarker>
|
123
|
+
<type>Step</type>
|
124
|
+
<thumbnail-url>http://img.howcast.com/system/thumbnails/233/32.jpg</thumbnail-url>
|
125
|
+
<title>Sit down on mat</title>
|
126
|
+
<textile-text>
|
127
|
+
<![CDATA[Sit down on the mat with your legs straight out in front of you.]]>
|
128
|
+
</textile-text>
|
129
|
+
<text>
|
130
|
+
<![CDATA[<p>Sit down on the mat with your legs straight out in front of you.</p>]]>
|
131
|
+
</text>
|
132
|
+
</marker>
|
133
|
+
<marker>
|
134
|
+
<id>3719</id>
|
135
|
+
<position>4</position>
|
136
|
+
<timemarker>48</timemarker>
|
137
|
+
<type>Tip</type>
|
138
|
+
<thumbnail-url></thumbnail-url>
|
139
|
+
<title></title>
|
140
|
+
<textile-text>
|
141
|
+
<![CDATA[It's okay to slightly bend at the knees while extending into this pose.]]>
|
142
|
+
</textile-text>
|
143
|
+
<text>
|
144
|
+
<![CDATA[<p>It’s okay to slightly bend at the knees while extending into this pose.</p>]]>
|
145
|
+
</text>
|
146
|
+
</marker>
|
147
|
+
<marker>
|
148
|
+
<id>3723</id>
|
149
|
+
<position>8</position>
|
150
|
+
<timemarker>70</timemarker>
|
151
|
+
<type>Step</type>
|
152
|
+
<thumbnail-url>http://img.howcast.com/system/thumbnails/233/70.jpg</thumbnail-url>
|
153
|
+
<title>Release pose</title>
|
154
|
+
<textile-text>
|
155
|
+
<![CDATA[To release the pose, inhale, and raise your torso straight up with your arms stretched overhead, then exhale and lower your hands to the floor. Now to conquer kickball...]]>
|
156
|
+
</textile-text>
|
157
|
+
<text>
|
158
|
+
<![CDATA[<p>To release the pose, inhale, and raise your torso straight up with your arms stretched overhead, then exhale and lower your hands to the floor. Now to conquer kickball…</p>]]>
|
159
|
+
</text>
|
160
|
+
</marker>
|
161
|
+
<marker>
|
162
|
+
<id>3724</id>
|
163
|
+
<position>9</position>
|
164
|
+
<timemarker>81</timemarker>
|
165
|
+
<type>Fact</type>
|
166
|
+
<thumbnail-url></thumbnail-url>
|
167
|
+
<title></title>
|
168
|
+
<textile-text>
|
169
|
+
<![CDATA[Pop nobility Sting recently admitted that he and his wife's claims of yoga-inspired marathons of tantric sex was all a joke, saying, "I have frantic sex, not tantric sex."]]>
|
170
|
+
</textile-text>
|
171
|
+
<text>
|
172
|
+
<![CDATA[<p>Pop nobility Sting recently admitted that he and his wife’s claims of yoga-inspired marathons of tantric sex was all a joke, saying, “I have frantic sex, not tantric sex.”</p>]]>
|
173
|
+
</text>
|
174
|
+
</marker>
|
175
|
+
</markers>
|
176
|
+
<related-videos>
|
177
|
+
<video>
|
178
|
+
<category-id>515</category-id>
|
179
|
+
<id>224</id>
|
180
|
+
<title>How To Do the Extended Triangle Pose</title>
|
181
|
+
<views>2470</views>
|
182
|
+
<type>HowcastGuide</type>
|
183
|
+
<created-at>Wed, 05 Dec 2007 20:07:04 -0800</created-at>
|
184
|
+
<rating>6</rating>
|
185
|
+
<username>joekulak</username>
|
186
|
+
<description>
|
187
|
+
<![CDATA[What do paintings on a wall, car tires, and promising horoscopes have in common? They all require proper alignment. It's not the easiest skill to acquire, but the Extended Triangle Pose will help hone it.]]>
|
188
|
+
</description>
|
189
|
+
<embed>
|
190
|
+
<![CDATA[<object width="425" height="352" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="howcastplayer"><param name="movie" value="http://www.howcast.com/flash/howcast_player.swf?file=224"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.howcast.com/flash/howcast_player.swf?file=224" type="application/x-shockwave-flash" width="425" height="352" allowFullScreen="true" allowScriptAccess="always" ></embed></object>]]>
|
191
|
+
</embed>
|
192
|
+
<duration>146</duration>
|
193
|
+
<filename>http://media.howcast.com/system/videos/0/24/02/224.flv</filename>
|
194
|
+
<tags>DIY, Instructional, tutorial, Do It Yourself, Tips, Essential Skills, Learn to, yoga, pose, position, body, exercise, stretch, meditation, extended, triangle, utthita, trikonasana, warrior</tags>
|
195
|
+
<category-hierarchy>
|
196
|
+
<category id="479">Health & Nutrition</category>
|
197
|
+
<category parent_id="479" id="510">Exercise</category>
|
198
|
+
<category parent_id="510" id="515">Yoga</category>
|
199
|
+
</category-hierarchy>
|
200
|
+
<comment-count>0</comment-count>
|
201
|
+
<thumbnail-url>http://img.howcast.com/system/thumbnails/224/Mind.How_to_Do_the_Extended_Triangle_Pose_SD_xxlarge_maintained_aspect.jpg</thumbnail-url>
|
202
|
+
<permalink>http://www.howcast.com/videos/224-How-To-Do-the-Extended-Triangle-Pose</permalink>
|
203
|
+
<content_rating>nonadult</content_rating>
|
204
|
+
</video>
|
205
|
+
<video>
|
206
|
+
<category-id>515</category-id>
|
207
|
+
<id>225</id>
|
208
|
+
<title>How To Do a Seated Spinal Twist Pose</title>
|
209
|
+
<views>3461</views>
|
210
|
+
<type>HowcastGuide</type>
|
211
|
+
<created-at>Wed, 05 Dec 2007 20:07:08 -0800</created-at>
|
212
|
+
<rating>8</rating>
|
213
|
+
<username>joekulak</username>
|
214
|
+
<description>
|
215
|
+
<![CDATA[According to Hindu mythology, this pose was originated by a yogi who spent 12 years in the belly of a fish, eavesdropping on Shiva's secret yoga instructions in an ocean cave. All you have to do is sit on a mat.]]>
|
216
|
+
</description>
|
217
|
+
<embed>
|
218
|
+
<![CDATA[<object width="425" height="352" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="howcastplayer"><param name="movie" value="http://www.howcast.com/flash/howcast_player.swf?file=225"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.howcast.com/flash/howcast_player.swf?file=225" type="application/x-shockwave-flash" width="425" height="352" allowFullScreen="true" allowScriptAccess="always" ></embed></object>]]>
|
219
|
+
</embed>
|
220
|
+
<duration>143</duration>
|
221
|
+
<filename>http://media.howcast.com/system/videos/1/25/02/225.flv</filename>
|
222
|
+
<tags>DIY, Instructional, tutorial, Do It Yourself, Tips, Essential Skills, Learn to, yoga, pose, position, body, exercise, stretch, meditation, seated, spinal, twist, Ardha, Matsyendrasana</tags>
|
223
|
+
<category-hierarchy>
|
224
|
+
<category id="479">Health & Nutrition</category>
|
225
|
+
<category parent_id="479" id="510">Exercise</category>
|
226
|
+
<category parent_id="510" id="515">Yoga</category>
|
227
|
+
</category-hierarchy>
|
228
|
+
<comment-count>0</comment-count>
|
229
|
+
<thumbnail-url>http://img.howcast.com/system/thumbnails/225/Mind.How_to_Do_a_Seated_Spinal_Twist_Pose_SD_xxlarge_maintained_aspect.jpg</thumbnail-url>
|
230
|
+
<permalink>http://www.howcast.com/videos/225-How-To-Do-a-Seated-Spinal-Twist-Pose</permalink>
|
231
|
+
<content_rating>nonadult</content_rating>
|
232
|
+
</video>
|
233
|
+
</related-videos>
|
99
234
|
</video>
|
100
235
|
</howcast>
|
101
236
|
VID
|
102
237
|
end
|
103
238
|
|
104
|
-
def guides_xml
|
105
|
-
<<-VID
|
106
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
107
|
-
<howcast version="0.1">
|
108
|
-
<title>Howcast - Top Favorites Howcast Written Guides </title>
|
109
|
-
<guides>
|
110
|
-
<guide>
|
111
|
-
<rating>94</rating>
|
112
|
-
<title>How To Pretend You’re a Real New Yorker</title>
|
113
|
-
<permalink>http://www.howcast.com/guides/1101-How-To-Pretend-Youre-a-Real-New-Yorker</permalink>
|
114
|
-
<id>1101</id>
|
115
|
-
<category-id>1642</category-id>
|
116
|
-
<description>There’s nothing wrong with being a tourist in New York City. But if you want to blend in, here’s what you need to know.</description>
|
117
|
-
<views>2739</views>
|
118
|
-
<username>vinzfeller</username>
|
119
|
-
<created-at>2008-02-05T19:41:21-08:00</created-at>
|
120
|
-
</guide>
|
121
|
-
<guide>
|
122
|
-
<rating>96</rating>
|
123
|
-
<title>How To Look Great in Photographs</title>
|
124
|
-
<permalink>http://www.howcast.com/guides/577-How-To-Look-Great-in-Photographs</permalink>
|
125
|
-
<id>577</id>
|
126
|
-
<category-id>22</category-id>
|
127
|
-
<description>Sure, a beautiful photograph takes some skill behind the lens, but it takes a little skill in front of it, too.</description>
|
128
|
-
<views>3831</views>
|
129
|
-
<username>nicholas</username>
|
130
|
-
<created-at>2008-01-12T09:33:06-08:00</created-at>
|
131
|
-
</guide>
|
132
|
-
<guide>
|
133
|
-
<rating>98</rating>
|
134
|
-
<title>How To Make a Water Gun Alarm Clock</title>
|
135
|
-
<permalink>http://www.howcast.com/guides/866-How-To-Make-a-Water-Gun-Alarm-Clock</permalink>
|
136
|
-
<id>866</id>
|
137
|
-
<category-id>1728</category-id>
|
138
|
-
<description>Having a little trouble waking up in the morning? There’s nothing like a good soaking to get you going.</description>
|
139
|
-
<views>2663</views>
|
140
|
-
<username>Howcast</username>
|
141
|
-
<created-at>2008-01-31T20:47:08-08:00</created-at>
|
142
|
-
</guide>
|
143
|
-
</guides>
|
144
|
-
</howcast>
|
145
|
-
VID
|
146
|
-
end
|
147
|
-
|
148
239
|
def videos_xml
|
149
240
|
<<-VID
|
150
241
|
<?xml version="1.0" encoding="UTF-8"?>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: howcast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jingshen Jimmy Zhang
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-03-
|
13
|
+
date: 2010-03-08 00:00:00 -08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -53,6 +53,7 @@ files:
|
|
53
53
|
- lib/howcast/client.rb
|
54
54
|
- lib/howcast/client/base.rb
|
55
55
|
- lib/howcast/client/category.rb
|
56
|
+
- lib/howcast/client/marker.rb
|
56
57
|
- lib/howcast/client/search.rb
|
57
58
|
- lib/howcast/client/video.rb
|
58
59
|
- lib/howcast/errors.rb
|
@@ -91,16 +92,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
92
|
requirements: []
|
92
93
|
|
93
94
|
rubyforge_project:
|
94
|
-
rubygems_version: 1.3.
|
95
|
+
rubygems_version: 1.3.4
|
95
96
|
signing_key:
|
96
97
|
specification_version: 3
|
97
98
|
summary: Howcast API Ruby Wrapper
|
98
99
|
test_files:
|
99
|
-
- spec/output_capture_helper.rb
|
100
|
-
- spec/xml_fixtures_helper.rb
|
101
|
-
- spec/string_matchers_helper.rb
|
102
|
-
- spec/spec_helper.rb
|
103
100
|
- spec/howcast/client/base_spec.rb
|
104
|
-
- spec/howcast/client/video_spec.rb
|
105
101
|
- spec/howcast/client/category_spec.rb
|
106
102
|
- spec/howcast/client/search_spec.rb
|
103
|
+
- spec/howcast/client/video_spec.rb
|
104
|
+
- spec/output_capture_helper.rb
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
- spec/string_matchers_helper.rb
|
107
|
+
- spec/xml_fixtures_helper.rb
|