howcast 0.4.3 → 0.4.10

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,15 @@
1
+ == 0.4.9 2009-08-19
2
+
3
+ * require hpricot, update readme
4
+
5
+ == 0.4.8 2009-08-19
6
+
7
+ * Move gem to github, use echoe to clean up configuration, remove dependency on hpricot
8
+
9
+ == 0.4.5 2009-07-27
10
+
11
+ * Removed guide wrappers, Howcast API just has how-to's which merges old video and guides
12
+
1
13
  == 0.4.3 2009-03-02
2
14
 
3
15
  * Compatibility with ruby 1.9 - replacing dependency on hpricot with why-hpricot as github as the ruby 1.9 hpricot gem
data/Manifest ADDED
@@ -0,0 +1,19 @@
1
+ CHANGELOG
2
+ lib/howcast/client/base.rb
3
+ lib/howcast/client/category.rb
4
+ lib/howcast/client/search.rb
5
+ lib/howcast/client/video.rb
6
+ lib/howcast/client.rb
7
+ lib/howcast/errors.rb
8
+ lib/howcast.rb
9
+ License.txt
10
+ Manifest
11
+ Rakefile
12
+ README.markdown
13
+ spec/howcast/client/base_spec.rb
14
+ spec/howcast/client/category_spec.rb
15
+ spec/howcast/client/search_spec.rb
16
+ spec/howcast/client/video_spec.rb
17
+ spec/spec.opts
18
+ spec/spec_helper.rb
19
+ tasks/github.rake
data/README.markdown CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Copyright (c) 2008 Howcast Media Inc.
4
4
 
5
- Author: Michael Murray <michael@howcast.com>
5
+ Author: Jingshen Jimmy Zhang <jimmy@howcast.com>
6
6
 
7
7
  ## Installing
8
8
 
9
- sudo gem install howcast
9
+ sudo gem install howcast-howcast
10
10
 
11
11
  ## Example
12
12
 
@@ -20,14 +20,14 @@ Author: Michael Murray <michael@howcast.com>
20
20
  puts v.title
21
21
  end
22
22
 
23
- puts "2nd Page of Recent Featured Videos"
24
- # Will print out the video titles of the 2nd page of recent featured videos
25
- hc.videos(:page => 2, :sort => "most_recent", :filter => "featured").each do |v|
23
+ puts "2nd Page of Top Rated Videos"
24
+ # Will print out the video titles of the 2nd page of top rated videos
25
+ hc.videos(:page => 2, :sort => "top_rated", :filter => "all").each do |v|
26
26
  puts v.title
27
27
  end
28
28
 
29
29
  puts "Videos matching 'origami'"
30
- hc.video_search("origami").each do |v|
30
+ hc.search("origami").each do |v|
31
31
  puts v.title
32
32
  end
33
33
 
data/Rakefile CHANGED
@@ -1,4 +1,32 @@
1
- require 'config/requirements'
2
- require 'config/hoe' # setup Hoe + all gem configuration
1
+ require 'rubygems'
2
+ require 'rake'
3
3
 
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gemspec|
7
+ gemspec.name = "howcast"
8
+ gemspec.summary = "Howcast API Ruby Wrapper"
9
+ gemspec.description = <<-EOS
10
+ Howcast offers an Application Programming Interface (API) which allows
11
+ developers to build applications that interface with Howcast. The Howcast
12
+ API is RESTful (REpresentational State Transfer) and users of this API will
13
+ be able: 1) Retreive detailed information about a single video, including
14
+ metadata such as title, description, video views, rating etc; 2) Retrieve a
15
+ list of videos restricted by a set of filters offered by Howcast and sorted
16
+ using several metrics that you can specify (most recent, most views, etc);
17
+ 3) Search for video; 4) And much more. Note: Before you can use our APIs,
18
+ you must register an API key, that is submitted with each request.
19
+ EOS
20
+ gemspec.email = "support@howcast.com"
21
+ gemspec.homepage = "http://github.com/howcast/howcast-gem"
22
+ gemspec.authors = ["Jingshen Jimmy Zhang", "Ian Smith-Heisters"]
23
+ gemspec.add_dependency "hpricot"
24
+ gemspec.add_development_dependency "rspec"
25
+ gemspec.files = FileList['**/*'].exclude('tmp/*', 'script/*', 'tags', 'pkg')
26
+ end
27
+ rescue LoadError
28
+ puts "Jeweler not available. Install it with: gem install jeweler"
29
+ end
30
+
31
+
32
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.4.10
data/howcast.gemspec ADDED
@@ -0,0 +1,79 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{howcast}
8
+ s.version = "0.4.10"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jingshen Jimmy Zhang", "Ian Smith-Heisters"]
12
+ s.date = %q{2010-01-04}
13
+ s.description = %q{ Howcast offers an Application Programming Interface (API) which allows
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
+ }
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.gemspec",
35
+ "lib/howcast.rb",
36
+ "lib/howcast/client.rb",
37
+ "lib/howcast/client/base.rb",
38
+ "lib/howcast/client/category.rb",
39
+ "lib/howcast/client/search.rb",
40
+ "lib/howcast/client/video.rb",
41
+ "lib/howcast/errors.rb",
42
+ "spec/howcast/client/base_spec.rb",
43
+ "spec/howcast/client/category_spec.rb",
44
+ "spec/howcast/client/search_spec.rb",
45
+ "spec/howcast/client/video_spec.rb",
46
+ "spec/spec.opts",
47
+ "spec/spec_helper.rb",
48
+ "tasks/github.rake"
49
+ ]
50
+ s.homepage = %q{http://github.com/howcast/howcast-gem}
51
+ s.rdoc_options = ["--charset=UTF-8"]
52
+ s.require_paths = ["lib"]
53
+ s.rubygems_version = %q{1.3.5}
54
+ s.summary = %q{Howcast API Ruby Wrapper}
55
+ s.test_files = [
56
+ "spec/howcast/client/base_spec.rb",
57
+ "spec/howcast/client/category_spec.rb",
58
+ "spec/howcast/client/search_spec.rb",
59
+ "spec/howcast/client/video_spec.rb",
60
+ "spec/spec_helper.rb"
61
+ ]
62
+
63
+ if s.respond_to? :specification_version then
64
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
65
+ s.specification_version = 3
66
+
67
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
68
+ s.add_runtime_dependency(%q<hpricot>, [">= 0"])
69
+ s.add_development_dependency(%q<rspec>, [">= 0"])
70
+ else
71
+ s.add_dependency(%q<hpricot>, [">= 0"])
72
+ s.add_dependency(%q<rspec>, [">= 0"])
73
+ end
74
+ else
75
+ s.add_dependency(%q<hpricot>, [">= 0"])
76
+ s.add_dependency(%q<rspec>, [">= 0"])
77
+ end
78
+ end
79
+
data/lib/howcast.rb CHANGED
@@ -4,6 +4,5 @@ def require_local(suffix)
4
4
  require(File.expand_path(File.join(File.dirname(__FILE__), suffix)))
5
5
  end
6
6
 
7
- require_local('howcast/version')
8
7
  require_local('howcast/client')
9
8
  require_local('howcast/errors')
@@ -4,6 +4,5 @@ end
4
4
 
5
5
  require_local('howcast/client/base.rb')
6
6
  require_local('howcast/client/video.rb')
7
- require_local('howcast/client/guide.rb')
8
7
  require_local('howcast/client/search.rb')
9
8
  require_local('howcast/client/category.rb')
@@ -24,6 +24,7 @@
24
24
  require 'rubygems'
25
25
  require 'hpricot'
26
26
  require 'open-uri'
27
+ require 'uri'
27
28
 
28
29
  class Howcast::Client
29
30
  attr_accessor :key
@@ -43,7 +44,21 @@ class Howcast::Client
43
44
  raise Howcast::ApiKeyNotFound if options[:key].nil?
44
45
  @key = options[:key]
45
46
  end
46
-
47
+
48
+ class << self
49
+ def base_uri= new_base_uri
50
+ @base_uri = case new_base_uri
51
+ when URI then new_base_uri
52
+ when String then URI.parse new_base_uri
53
+ when Hash then URI::HTTP.build new_base_uri
54
+ else; raise ArgumentError, "can't convert URI: #{new_base_uri.inspect}"
55
+ end
56
+ end
57
+
58
+ def base_uri
59
+ @base_uri ||= URI.parse("http://www.howcast.com")
60
+ end
61
+ end
47
62
  protected
48
63
  # Establishes a connection with the Howcast API. Will auto append the api key, that was used
49
64
  # to instantiate the Client object, to the URL
@@ -65,8 +80,11 @@ class Howcast::Client
65
80
  #
66
81
  # Get the Hpricot data for most recent howcast studios videos
67
82
  # establish_connection("videos/most_recent/howcast_studios.xml")
68
- def establish_connection(relative_path)
69
- h = Hpricot.XML(open(url = attach_api_key("http://www.howcast.com/#{relative_path}")))
83
+ def establish_connection(relative_path_and_query)
84
+ uri = self.class.base_uri.dup
85
+ relative_path_and_query = '/' + relative_path_and_query unless relative_path_and_query[0] == '/'
86
+ uri.path, uri.query = *relative_path_and_query.split('?')
87
+ h = Hpricot.XML(open(url = attach_api_key(uri)))
70
88
  puts "Established connection with: '#{url}'"
71
89
  raise Howcast::ApiKeyNotFound if h.at(:error) && h.at(:error).inner_html.match(/Invalid API Key/)
72
90
  return h
@@ -79,10 +97,10 @@ class Howcast::Client
79
97
  # === Inputs
80
98
  #
81
99
  # * <tt>xml</tt> -- See below for a sample xml input
82
- # * <tt>klass</tt> -- Class to create - Guide | Video | Category supported
100
+ # * <tt>klass</tt> -- Class to create - Video | Category supported
83
101
  #
84
102
  # Sample input xml
85
- # <guide>
103
+ # <video>
86
104
  # <id>1086</id>
87
105
  # <rating>96</rating>
88
106
  # <title>How To Choose a Paintbrush</title>
@@ -94,7 +112,7 @@ class Howcast::Client
94
112
  # <permalink>http://www.howcast.com/guides/1086-How-To-Choose-a-Paintbrush</permalink>
95
113
  # <username>michaelrsanchez</username>
96
114
  # <created-at>Thu, 20 Dec 2007 14:14:58 -0800</created-at>
97
- # </guide>
115
+ # </video>
98
116
  #
99
117
  # === Outputs
100
118
  #
@@ -130,25 +148,55 @@ class Howcast::Client
130
148
  opts && opts[:page] ? "#{opts[:use_ampersand] ? '&' : '?'}page=#{opts[:page]}" : ""
131
149
  end
132
150
 
133
- # Appends the api key to a url and returns the appended url
151
+ # Appends the api key to a uri and returns the appended uri
134
152
  #
135
153
  # === Inputs
136
154
  #
137
- # * <tt>url</tt> -- the url to append the api_key to
155
+ # * <tt>uri</tt> -- the URI object to append the api_key to
138
156
  #
139
157
  # === Outputs
140
158
  #
141
- # The url with the api_key appended
159
+ # The uri with the api_key appended to the query string
142
160
  #
143
161
  # === Examples
144
162
  #
145
- # attach_api_key("http://www.howcast.com")
163
+ # attach_api_key(URI.parse("http://www.howcast.com")).to_s
146
164
  # => "http://www.howcast.com?api_key=APIKEYHERE"
147
165
  #
148
- # attach_api_key("http://www.howcast.com/videos/most_recent/all?page=2")
166
+ # attach_api_key(URI.parse("http://www.howcast.com/videos/most_recent/all?page=2")).to_s
149
167
  # => "http://www.howcast.com/videos/most_recent/all?page=2&api_key=APIKEYHERE"
150
- def attach_api_key(url)
151
- url.match(/\?/) ? "#{url}&api_key=#{self.key}" : "#{url}?api_key=#{self.key}"
168
+ def attach_api_key(uri)
169
+ uri = uri.dup
170
+ key = "api_key=#{self.key}"
171
+ uri.query = uri.query.to_s.strip != "" ? uri.query+"&"+key : key
172
+ uri
173
+ end
174
+
175
+ # From merb/core_ext/hash.rb, line 87
176
+ def hash_to_params hash
177
+ params = ''
178
+ stack = []
179
+
180
+ hash.each do |k, v|
181
+ if v.is_a?(Hash)
182
+ stack << [k,v]
183
+ else
184
+ params << "#{k}=#{v}&"
185
+ end
186
+ end
187
+
188
+ stack.each do |parent, h|
189
+ h.each do |k, v|
190
+ if v.is_a?(Hash)
191
+ stack << ["#{parent}[#{k}]", v]
192
+ else
193
+ params << "#{parent}[#{k}]=#{v}&"
194
+ end
195
+ end
196
+ end
197
+
198
+ params.chop! # trailing &
199
+ params
152
200
  end
153
201
  end
154
202
 
@@ -25,13 +25,15 @@ require 'cgi'
25
25
 
26
26
  class Howcast::Client
27
27
  # Provides access to the Howcast video search API.
28
- #
28
+ #
29
29
  # === Inputs
30
30
  #
31
- # * <tt>query</tt> -- The string query which you want to search for
32
- # The options are:
33
- # * <tt>:page</tt> -- The page number to retrieve (defaults to 1). There are 10 videos per page.
34
- # * <tt>:mode</tt> -- Mode to search, using :extended will allow title:something searches
31
+ # * <tt>query</tt> -- The string query which you want to search for
32
+ # The options are:
33
+ # ** <tt>:page</tt> -- The page number to retrieve (defaults to 1). There are
34
+ # 10 videos per page.
35
+ # ** <tt>:mode</tt> -- Mode to search, using :extended will allow
36
+ # title:something searches
35
37
  #
36
38
  # === Outputs
37
39
  #
@@ -39,43 +41,46 @@ class Howcast::Client
39
41
  #
40
42
  # === Exceptions
41
43
  #
42
- # * <tt>Howcast::ApiNotFound</tt> -- raised if the requested sort and filter is malformed or not available (404)
43
- # * <tt>ArgumentError</tt> -- raised when the required 1 argument isn't supplied
44
+ # * <tt>Howcast::ApiNotFound</tt> -- raised if the requested sort and filter
45
+ # is malformed or not available (404)
46
+ # * <tt>ArgumentError</tt> -- raised when the required 1 argument isn't
47
+ # supplied
44
48
  #
45
49
  # === Examples
46
50
  #
47
- # Get the first page of howcast videos matching 'poker'.
51
+ # Get the first page of howcast videos matching 'poker'.
48
52
  # Howcast::Client.new.video_search("poker")
49
53
  # Get the third page of howcast videos matching 'traveling'
50
54
  # Howcast::Client.new.video_search("traveling", :page => 3)
51
- def video_search(query, options = {})
52
- uri = search_url(query, options.merge(:view => 'video'))
53
- (establish_connection(uri)/:video).inject([]){ |r, i| r << parse_single_xml(i, Video)}
55
+ def search(query, options = {})
56
+ defaults = {:view => "videos", :q => query}
57
+ params = defaults.merge options
58
+ do_search params
54
59
  end
55
-
56
- # Provides access to the Howcast wiki guide search API.
57
- #
58
- # See video_search documentation for inputs, outputs and exceptions
60
+
61
+ # Provides low-level access to the Howcast video search API.
59
62
  #
60
- # === Examples
63
+ # === Inputs
61
64
  #
62
- # Get the first page of howcast wiki guides matching 'poker'.
63
- # Howcast::Client.new.guide_search("poker")
64
- # Get the third page of howcast wiki guides matching 'traveling'
65
- # Howcast::Client.new.guide_search("traveling", :page => 3)
66
- def guide_search(query, options = {})
67
- uri = search_url(query, options.merge(:view => 'guide'))
68
- (establish_connection(uri)/:guide).inject([]){ |r, i| r << parse_single_xml(i, Guide) }
65
+ # * <tt>params</tt> -- A hash of params that will be URL encoded and appended
66
+ # to the URI. You'll have to know what you're doing.
67
+ #
68
+ # Other than its arguments, this method is identical to +search+.
69
+ def advanced_search params
70
+ do_search params
69
71
  end
70
-
71
- private
72
- def search_url(query, options={})
73
- defaults = {:page => nil, :view => nil, :mode => nil}
74
- options = defaults.update(options)
75
- query = CGI.escape(query)
76
- uri = "search.xml?q=#{query}"
77
- uri += "&view=#{options[:view]}" unless options[:view].nil?
78
- uri += "&mode=extended" if (options[:mode] == :extended)
79
- uri + uri_suffix(options.merge(:use_ampersand => true))
72
+
73
+ private
74
+ def do_search params
75
+ uri = search_url params
76
+ (establish_connection(uri)/:video).inject([]){ |r, i| r << parse_single_xml(i, Video)}
77
+ end
78
+
79
+ def search_url params
80
+ uri = "search.xml?"
81
+ params[:q] = CGI.escape params[:q] if params[:q]
82
+ uri += hash_to_params params
83
+ uri += uri_suffix(params.merge(:use_ampersand => true)) unless params[:page]
84
+ uri
80
85
  end
81
86
  end
@@ -90,9 +90,9 @@ class Howcast::Client
90
90
  # === Inputs
91
91
  #
92
92
  # The options are:
93
- # * <tt>:page</tt> -- The page number to retrieve (defaults to 1). There are 16 videos per page.
94
- # * <tt>:sort</tt> -- One of +most_recent+ (default) | +most_viewed+ | +top_rated+ | +most_emailed+ | +most_discussed+ | +top_favorites+
95
- # * <tt>:filter</tt> -- One of +all+ | +featured+ | +howcast_studios+ (default) | +directors_program+ | +community+
93
+ # * <tt>:page</tt> -- The page number to retrieve (defaults to 1). There are 20 videos per page.
94
+ # * <tt>:sort</tt> -- One of +most_recent+ (default) | +most_viewed+ | +top_rated+
95
+ # * <tt>:filter</tt> -- One of +all+ | +howcast_studios+ (default)
96
96
  #
97
97
  # === Outputs
98
98
  # An array of video objects
@@ -105,7 +105,7 @@ class Howcast::Client
105
105
  # Get the first page of most recent howcast studios videos.
106
106
  # Howcast::Client.new.videos
107
107
  # Get the third page of top favorites which are featured
108
- # Howcast::Client.new.videos(:page => 3, :sort => "top_favorites", :filter => "featured")
108
+ # Howcast::Client.new.videos(:page => 3, :sort => "top_favorites", :filter => "top_rated")
109
109
  def videos(options = {})
110
110
  uri = videos_url(options)
111
111
  (establish_connection(uri)/:video).inject([]){ |r, i| r << parse_single_xml(i, Video)}