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.
@@ -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
@@ -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
@@ -6,3 +6,4 @@ require_local('howcast/client/base.rb')
6
6
  require_local('howcast/client/video.rb')
7
7
  require_local('howcast/client/guide.rb')
8
8
  require_local('howcast/client/search.rb')
9
+ require_local('howcast/client/category.rb')
@@ -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
@@ -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].nil?
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
@@ -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].nil?
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
@@ -1,8 +1,8 @@
1
1
  module Howcast #:nodoc:
2
2
  module Version #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 3
5
- TINY = 2
4
+ MINOR = 4
5
+ TINY = 1
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  class << self
@@ -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?page=2 when :page => 2" do
27
- @hc.should_receive(:open).with("http://www.howcast.com/guides/most_recent/howcast_written.xml?page=2&api_key=myapikey").and_return(guides_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?page=2 when :page => 2" do
71
- @hc.should_receive(:open).with("http://www.howcast.com/videos/most_recent/howcast_studios.xml?page=2&api_key=myapikey").and_return(videos_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
 
@@ -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>]]>
@@ -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
- Howcast
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>Howcast</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.3.2</a>
36
+ <a href="http://rubyforge.org/projects/howcast" class="numbers">0.4.1</a>
37
37
  </div>
38
- <h2>What</h2>
38
+ <h2>Howcast <span class="caps">API</span> Rubygem</h2>
39
39
 
40
40
 
41
- <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>
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>
@@ -1,8 +1,9 @@
1
- h1. Howcast
1
+
2
+ h2. Howcast API Rubygem
2
3
 
3
4
  h2. What
4
5
 
5
- Howcast RubyGem is a Ruby library for interacting with the "Howcast API":http://groups.google.com/group/howcast-developers
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.3.2
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-03 00:00:00 -07:00
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.1.0
108
+ rubygems_version: 1.2.0
96
109
  signing_key:
97
110
  specification_version: 2
98
111
  summary: Howcast API Ruby Wrapper