howcast 0.3.2 → 0.4.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/History.txt +17 -0
- data/Manifest.txt +2 -0
- data/lib/howcast/client.rb +1 -0
- data/lib/howcast/client/base.rb +1 -1
- data/lib/howcast/client/category.rb +85 -0
- data/lib/howcast/client/guide.rb +1 -7
- data/lib/howcast/client/video.rb +8 -7
- data/lib/howcast/version.rb +2 -2
- data/spec/howcast/client/category_spec.rb +45 -0
- data/spec/howcast/client/guide_spec.rb +2 -2
- data/spec/howcast/client/video_spec.rb +10 -2
- data/spec/spec_helper.rb +37 -0
- data/website/index.html +8 -5
- data/website/index.txt +3 -2
- metadata +16 -3
data/History.txt
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
== 0.4.1 2008-11-05
|
2
|
+
|
3
|
+
* Support for finding a category ancestor trail from a category object
|
4
|
+
|
5
|
+
== 0.4 2008-11-02
|
6
|
+
|
7
|
+
* Add support for the new category API to get the name and parent ID
|
8
|
+
* Added badges and easy_steps methods for video
|
9
|
+
|
10
|
+
== 0.3.4 2008-08-21
|
11
|
+
|
12
|
+
* Support for new paging scheme in browse pages - ?page=1 => /1
|
13
|
+
|
14
|
+
== 0.3.3 2008-07-25
|
15
|
+
|
16
|
+
* Video dimensions
|
17
|
+
|
1
18
|
== 0.3.2 2008-06-03
|
2
19
|
|
3
20
|
* Clean up with inject
|
data/Manifest.txt
CHANGED
@@ -13,6 +13,7 @@ lib/howcast/client/base.rb
|
|
13
13
|
lib/howcast/client/video.rb
|
14
14
|
lib/howcast/client/guide.rb
|
15
15
|
lib/howcast/client/search.rb
|
16
|
+
lib/howcast/client/category.rb
|
16
17
|
script/destroy
|
17
18
|
script/generate
|
18
19
|
script/txt2html
|
@@ -23,6 +24,7 @@ spec/howcast/client/base_spec.rb
|
|
23
24
|
spec/howcast/client/guide_spec.rb
|
24
25
|
spec/howcast/client/video_spec.rb
|
25
26
|
spec/howcast/client/search_spec.rb
|
27
|
+
spec/howcast/client/category_spec.rb
|
26
28
|
tasks/deployment.rake
|
27
29
|
tasks/environment.rake
|
28
30
|
tasks/rspec.rake
|
data/lib/howcast/client.rb
CHANGED
data/lib/howcast/client/base.rb
CHANGED
@@ -79,7 +79,7 @@ class Howcast::Client
|
|
79
79
|
# === Inputs
|
80
80
|
#
|
81
81
|
# * <tt>xml</tt> -- See below for a sample xml input
|
82
|
-
# * <tt>klass</tt> -- Class to create - Guide | Video supported
|
82
|
+
# * <tt>klass</tt> -- Class to create - Guide | Video | Category supported
|
83
83
|
#
|
84
84
|
# Sample input xml
|
85
85
|
# <guide>
|
@@ -0,0 +1,85 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2008 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 Category
|
26
|
+
extend WatchAttrAccessors
|
27
|
+
attr_accessor :id, :name, :parent_id, :parents
|
28
|
+
|
29
|
+
# Creates a new Category object which is used to encapsulate all the attributes available
|
30
|
+
# from the Howcast Category API. The parents attribute will be an array of category
|
31
|
+
# ancestors of the form:
|
32
|
+
# [{:id => 1, :name => 'root'}, {:id => 2, :name => 'immediate parent'}]
|
33
|
+
#
|
34
|
+
# === Inputs
|
35
|
+
#
|
36
|
+
# * <tt>attributes</tt> -- A hash to set the various attributes of the category object
|
37
|
+
#
|
38
|
+
# === Examples
|
39
|
+
#
|
40
|
+
# Initialize a category with name "Arts & Crafts"
|
41
|
+
# Category.new :name => "Arts & Crafts"
|
42
|
+
def initialize(attributes={})
|
43
|
+
attributes.each do |k, v|
|
44
|
+
self.send("#{k}=", v) if self.respond_to?(k)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Provides access to the Howcast category API.
|
50
|
+
#
|
51
|
+
# === Inputs
|
52
|
+
#
|
53
|
+
# * <tt>id</tt> -- The id of the category to lookup
|
54
|
+
#
|
55
|
+
# === Outputs
|
56
|
+
#
|
57
|
+
# Category object if the id exists or nil if the id doesn't exist or is malformed
|
58
|
+
#
|
59
|
+
# === Exceptions
|
60
|
+
#
|
61
|
+
# * <tt>Howcast::ApiNotFound</tt>
|
62
|
+
#
|
63
|
+
# === Examples
|
64
|
+
#
|
65
|
+
# Get the Howcast category with id 2
|
66
|
+
# Howcast::Client.new.category(2)
|
67
|
+
def category(id)
|
68
|
+
response = establish_connection("categories/#{id}.xml")
|
69
|
+
parse_single_category_xml(response.at(:category))
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
# Exception here to parse the <parents> tag in a category, will set a category.parents variable
|
74
|
+
# which is an array of parent metadata hases
|
75
|
+
# [{:id => '123', :name => "root"}, {:id => "1234", :name => "parent"}]
|
76
|
+
def parse_single_category_xml(xml)
|
77
|
+
hash = {}
|
78
|
+
Category.attr_accessors.each do |attribute|
|
79
|
+
node_name = attribute.to_s.gsub("_", "-") # xml schema uses hyphens for spaces, but ruby uses underscores
|
80
|
+
hash[attribute] = !xml.at(node_name).nil? ? xml.at(node_name).inner_text.strip : ""
|
81
|
+
end
|
82
|
+
hash[:parents] = (xml.at('parents')/:category).map{ |c| {:id => c['id'], :name => c.inner_html }}
|
83
|
+
hash.values.all?{|v| v==""} ? nil : Category.new(hash)
|
84
|
+
end
|
85
|
+
end
|
data/lib/howcast/client/guide.rb
CHANGED
@@ -44,7 +44,6 @@ class Howcast::Client
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
# REFACTOR: Consider combining with videos method
|
48
47
|
# Provides access to the Howcast list guides API.
|
49
48
|
#
|
50
49
|
# === Inputs
|
@@ -75,11 +74,6 @@ class Howcast::Client
|
|
75
74
|
def guides_url(options={})
|
76
75
|
defaults = {:page => nil, :sort => "most_recent", :filter => "howcast_written", :category_id => nil}
|
77
76
|
options = defaults.update(options)
|
78
|
-
if options[:category_id].
|
79
|
-
uri = "guides/#{options[:sort]}/#{options[:filter]}.xml"
|
80
|
-
else
|
81
|
-
uri = "guides/#{options[:sort]}/#{options[:filter]}/#{options[:category_id]}.xml"
|
82
|
-
end
|
83
|
-
uri + uri_suffix(options)
|
77
|
+
"guides/#{options[:sort]}/#{options[:filter]}#{"/#{options[:category_id]}" if options[:category_id]}#{"/#{options[:page]}" if options[:page]}.xml"
|
84
78
|
end
|
85
79
|
end
|
data/lib/howcast/client/video.rb
CHANGED
@@ -37,7 +37,8 @@ class Howcast::Client
|
|
37
37
|
class Video
|
38
38
|
extend WatchAttrAccessors
|
39
39
|
attr_accessor :id, :title, :permalink, :thumbnail_url, :category_id,
|
40
|
-
:views, :username, :duration, :created_at, :rating, :description
|
40
|
+
:views, :username, :duration, :created_at, :rating, :description, :width, :height,
|
41
|
+
:badges, :easy_steps
|
41
42
|
# Creates a new Video object which is used to encapsulate all the attributes available
|
42
43
|
# from the Howcast Video API
|
43
44
|
#
|
@@ -54,6 +55,11 @@ class Howcast::Client
|
|
54
55
|
self.send("#{k}=", v) if self.respond_to?(k)
|
55
56
|
end
|
56
57
|
end
|
58
|
+
|
59
|
+
# Return true if the video contains easy step by step directions, else false
|
60
|
+
def easy_steps?
|
61
|
+
easy_steps == "true"
|
62
|
+
end
|
57
63
|
end
|
58
64
|
|
59
65
|
# Provides access to the Howcast video API.
|
@@ -109,11 +115,6 @@ class Howcast::Client
|
|
109
115
|
def videos_url(options={})
|
110
116
|
defaults = {:page => nil, :sort => "most_recent", :filter => "howcast_studios", :category_id => nil}
|
111
117
|
options = defaults.update(options)
|
112
|
-
if options[:category_id].
|
113
|
-
uri = "videos/#{options[:sort]}/#{options[:filter]}.xml"
|
114
|
-
else
|
115
|
-
uri = "videos/#{options[:sort]}/#{options[:filter]}/#{options[:category_id]}.xml"
|
116
|
-
end
|
117
|
-
uri + uri_suffix(options)
|
118
|
+
"videos/#{options[:sort]}/#{options[:filter]}#{"/#{options[:category_id]}" if options[:category_id]}#{"/#{options[:page]}" if options[:page]}.xml"
|
118
119
|
end
|
119
120
|
end
|
data/lib/howcast/version.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Howcast::Client::Category, "initialize" do
|
4
|
+
it "should create a category object with all the inputted attributes" do
|
5
|
+
category = Howcast::Client::Category.new :name => "category_title"
|
6
|
+
category.name.should == 'category_title'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should ignore inputs which are not category attributes" do
|
10
|
+
category = Howcast::Client::Category.new :not_an_attribute => "value", :name => "category_title"
|
11
|
+
category.respond_to?(:not_an_attribute).should be_false
|
12
|
+
category.name.should == "category_title"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Howcast::Client, "category" do
|
17
|
+
before do
|
18
|
+
@hc = Howcast::Client.new(:key => "myapikey")
|
19
|
+
@hc.stub!(:open).and_return(category_xml)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should establish a connection with the correct category url" do
|
23
|
+
@hc.should_receive(:open).with("http://www.howcast.com/categories/2.xml?api_key=myapikey").and_return(category_xml)
|
24
|
+
@hc.category(2)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should raise Howcast::ApiKeyNotFound error when the response contains Invalid API Key" do
|
28
|
+
lambda {
|
29
|
+
@hc.stub!(:open).and_return(invalid_api_key_xml)
|
30
|
+
@hc.category(2)
|
31
|
+
}.should raise_error(Howcast::ApiKeyNotFound)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should set the title attribute in the category model response" do
|
35
|
+
@hc.category(2).name.should == "General African Travel"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should set the parent_id attribute in the category model response" do
|
39
|
+
@hc.category(2).parent_id.should == "1584"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should set the parents metadata hash" do
|
43
|
+
@hc.category(2).parents.should == [{:id => "1571", :name => "Travel"}, {:id => "1584", :name => "African Travel"}]
|
44
|
+
end
|
45
|
+
end
|
@@ -23,8 +23,8 @@ describe Howcast::Client, "guides" do
|
|
23
23
|
@hc.guides
|
24
24
|
end
|
25
25
|
|
26
|
-
it "should establish a connection with guides/most_recent/howcast_written.xml
|
27
|
-
@hc.should_receive(:open).with("http://www.howcast.com/guides/most_recent/howcast_written.xml?
|
26
|
+
it "should establish a connection with guides/most_recent/howcast_written/2.xml when :page => 2" do
|
27
|
+
@hc.should_receive(:open).with("http://www.howcast.com/guides/most_recent/howcast_written/2.xml?api_key=myapikey").and_return(guides_xml)
|
28
28
|
@hc.guides(:page => 2)
|
29
29
|
end
|
30
30
|
|
@@ -44,6 +44,14 @@ describe Howcast::Client, "video" do
|
|
44
44
|
@hc.video(2).views.should == "38"
|
45
45
|
end
|
46
46
|
|
47
|
+
it "should set the badges in the video model response" do
|
48
|
+
@hc.video(2).badges.should == "Howcast Studios"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set the easy_steps boolean in the video model response" do
|
52
|
+
@hc.video(2).easy_steps?.should be_true
|
53
|
+
end
|
54
|
+
|
47
55
|
it "should set the rating attribute in the video model response" do
|
48
56
|
@hc.video(2).rating.should == "2.0"
|
49
57
|
end
|
@@ -67,8 +75,8 @@ describe Howcast::Client, "videos" do
|
|
67
75
|
@hc.videos
|
68
76
|
end
|
69
77
|
|
70
|
-
it "should establish a connection with videos/most_recent/howcast_studios.xml
|
71
|
-
@hc.should_receive(:open).with("http://www.howcast.com/videos/most_recent/howcast_studios.xml?
|
78
|
+
it "should establish a connection with videos/most_recent/howcast_studios/2.xml when :page => 2" do
|
79
|
+
@hc.should_receive(:open).with("http://www.howcast.com/videos/most_recent/howcast_studios/2.xml?api_key=myapikey").and_return(videos_xml)
|
72
80
|
@hc.videos(:page => 2)
|
73
81
|
end
|
74
82
|
|
data/spec/spec_helper.rb
CHANGED
@@ -48,6 +48,41 @@ Spec::Runner.configure do |config|
|
|
48
48
|
VID
|
49
49
|
end
|
50
50
|
|
51
|
+
def category_xml
|
52
|
+
<<-CAT
|
53
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
54
|
+
<howcast version="0.1">
|
55
|
+
<category>
|
56
|
+
<id>1255</id>
|
57
|
+
<name>General African Travel</name>
|
58
|
+
<parent-id>1584</parent-id>
|
59
|
+
<parents>
|
60
|
+
<category id="1571">Travel</category>
|
61
|
+
<category parent_id="1571" id="1584">African Travel</category>
|
62
|
+
</parents>
|
63
|
+
<subcategories>
|
64
|
+
<category>
|
65
|
+
<id>1265</id>
|
66
|
+
<name>African Travel</name>
|
67
|
+
</category>
|
68
|
+
<category>
|
69
|
+
<id>1289</id>
|
70
|
+
<name>European Travel</name>
|
71
|
+
</category>
|
72
|
+
<category>
|
73
|
+
<id>1256</id>
|
74
|
+
<name>General Travel</name>
|
75
|
+
</category>
|
76
|
+
<category>
|
77
|
+
<id>1311</id>
|
78
|
+
<name>General U.S. Travel</name>
|
79
|
+
</category>
|
80
|
+
</subcategories>
|
81
|
+
</category>
|
82
|
+
</howcast>
|
83
|
+
CAT
|
84
|
+
end
|
85
|
+
|
51
86
|
def video_xml
|
52
87
|
<<-VID
|
53
88
|
<?xml version="1.0" encoding="UTF-8"?>
|
@@ -56,6 +91,8 @@ Spec::Runner.configure do |config|
|
|
56
91
|
<category-id>2</category-id>
|
57
92
|
<duration>22</duration>
|
58
93
|
<id>233</id>
|
94
|
+
<easy-steps>true</easy-steps>
|
95
|
+
<badges>Howcast Studios</badges>
|
59
96
|
<title>How To Do a Noble Pose</title>
|
60
97
|
<description>
|
61
98
|
<![CDATA[You recognize the Noble Pose as the dreaded "sit-and-reach" from your childhood gym class. A sample <a href="howcast.com">link</a>]]>
|
data/website/index.html
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
6
6
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
7
7
|
<title>
|
8
|
-
|
8
|
+
|
9
9
|
</title>
|
10
10
|
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
11
11
|
<style>
|
@@ -30,15 +30,18 @@
|
|
30
30
|
<body>
|
31
31
|
<div id="main">
|
32
32
|
|
33
|
-
<h1
|
33
|
+
<h1></h1>
|
34
34
|
<div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/howcast"; return false'>
|
35
35
|
<p>Get Version</p>
|
36
|
-
<a href="http://rubyforge.org/projects/howcast" class="numbers">0.
|
36
|
+
<a href="http://rubyforge.org/projects/howcast" class="numbers">0.4.1</a>
|
37
37
|
</div>
|
38
|
-
<h2>
|
38
|
+
<h2>Howcast <span class="caps">API</span> Rubygem</h2>
|
39
39
|
|
40
40
|
|
41
|
-
<
|
41
|
+
<h2>What</h2>
|
42
|
+
|
43
|
+
|
44
|
+
<p>Howcast Rubygem is a Ruby library for interacting with the <a href="http://groups.google.com/group/howcast-developers">Howcast <span class="caps">API</span></a></p>
|
42
45
|
|
43
46
|
|
44
47
|
<h2>Installing</h2>
|
data/website/index.txt
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
|
1
|
+
|
2
|
+
h2. Howcast API Rubygem
|
2
3
|
|
3
4
|
h2. What
|
4
5
|
|
5
|
-
Howcast
|
6
|
+
Howcast Rubygem is a Ruby library for interacting with the "Howcast API":http://groups.google.com/group/howcast-developers
|
6
7
|
|
7
8
|
|
8
9
|
h2. Installing
|
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
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Murray
|
@@ -9,11 +9,12 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-06
|
12
|
+
date: 2008-11-06 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hpricot
|
17
|
+
type: :runtime
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
@@ -21,6 +22,16 @@ dependencies:
|
|
21
22
|
- !ruby/object:Gem::Version
|
22
23
|
version: "0.6"
|
23
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.8.2
|
34
|
+
version:
|
24
35
|
description: Howcast API Ruby Wrapper
|
25
36
|
email:
|
26
37
|
- michael+gem@howcast.com
|
@@ -50,6 +61,7 @@ files:
|
|
50
61
|
- lib/howcast/client/video.rb
|
51
62
|
- lib/howcast/client/guide.rb
|
52
63
|
- lib/howcast/client/search.rb
|
64
|
+
- lib/howcast/client/category.rb
|
53
65
|
- script/destroy
|
54
66
|
- script/generate
|
55
67
|
- script/txt2html
|
@@ -60,6 +72,7 @@ files:
|
|
60
72
|
- spec/howcast/client/guide_spec.rb
|
61
73
|
- spec/howcast/client/video_spec.rb
|
62
74
|
- spec/howcast/client/search_spec.rb
|
75
|
+
- spec/howcast/client/category_spec.rb
|
63
76
|
- tasks/deployment.rake
|
64
77
|
- tasks/environment.rake
|
65
78
|
- tasks/rspec.rake
|
@@ -92,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
105
|
requirements: []
|
93
106
|
|
94
107
|
rubyforge_project: howcast
|
95
|
-
rubygems_version: 1.
|
108
|
+
rubygems_version: 1.2.0
|
96
109
|
signing_key:
|
97
110
|
specification_version: 2
|
98
111
|
summary: Howcast API Ruby Wrapper
|