howcast 0.4.3 → 0.4.10
Sign up to get free protection for your applications and to get access to all the features.
- data/{History.txt → CHANGELOG} +12 -0
- data/Manifest +19 -0
- data/README.markdown +6 -6
- data/Rakefile +31 -3
- data/VERSION +1 -0
- data/howcast.gemspec +79 -0
- data/lib/howcast.rb +0 -1
- data/lib/howcast/client.rb +0 -1
- data/lib/howcast/client/base.rb +61 -13
- data/lib/howcast/client/search.rb +38 -33
- data/lib/howcast/client/video.rb +4 -4
- data/spec/howcast/client/base_spec.rb +41 -1
- data/spec/howcast/client/category_spec.rb +2 -2
- data/spec/howcast/client/search_spec.rb +57 -60
- data/spec/howcast/client/video_spec.rb +7 -7
- data/spec/spec_helper.rb +23 -1
- data/tasks/github.rake +3 -0
- metadata +36 -49
- data/Manifest.txt +0 -36
- data/config/hoe.rb +0 -70
- data/config/requirements.rb +0 -17
- data/lib/howcast/client/guide.rb +0 -79
- data/lib/howcast/version.rb +0 -20
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -74
- data/setup.rb +0 -1585
- data/spec/howcast/client/guide_spec.rb +0 -65
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/rspec.rake +0 -21
- data/tasks/website.rake +0 -17
- data/website/index.html +0 -101
- data/website/index.txt +0 -70
- data/website/javascripts/rounded_corners_lite.inc.js +0 -285
- data/website/stylesheets/screen.css +0 -138
- data/website/template.rhtml +0 -48
data/{History.txt → CHANGELOG}
RENAMED
@@ -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:
|
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
|
24
|
-
# Will print out the video titles of the 2nd page of
|
25
|
-
hc.videos(:page => 2, :sort => "
|
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.
|
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 '
|
2
|
-
require '
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
3
|
|
4
|
-
|
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
data/lib/howcast/client.rb
CHANGED
data/lib/howcast/client/base.rb
CHANGED
@@ -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(
|
69
|
-
|
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 -
|
100
|
+
# * <tt>klass</tt> -- Class to create - Video | Category supported
|
83
101
|
#
|
84
102
|
# Sample input xml
|
85
|
-
# <
|
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
|
-
# </
|
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
|
151
|
+
# Appends the api key to a uri and returns the appended uri
|
134
152
|
#
|
135
153
|
# === Inputs
|
136
154
|
#
|
137
|
-
# * <tt>
|
155
|
+
# * <tt>uri</tt> -- the URI object to append the api_key to
|
138
156
|
#
|
139
157
|
# === Outputs
|
140
158
|
#
|
141
|
-
# The
|
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(
|
151
|
-
|
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
|
-
#
|
33
|
-
#
|
34
|
-
#
|
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
|
43
|
-
#
|
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
|
-
|
52
|
-
|
53
|
-
|
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
|
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
|
-
# ===
|
63
|
+
# === Inputs
|
61
64
|
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
|
67
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
uri
|
79
|
-
|
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
|
data/lib/howcast/client/video.rb
CHANGED
@@ -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
|
94
|
-
# * <tt>:sort</tt> -- One of +most_recent+ (default) | +most_viewed+ | +top_rated+
|
95
|
-
# * <tt>:filter</tt> -- One of +all+ | +
|
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 => "
|
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)}
|