howcast 0.4.11 → 0.4.12
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/Rakefile +9 -0
- data/VERSION +1 -1
- data/howcast.gemspec +13 -7
- data/lib/howcast.rb +5 -4
- data/lib/howcast/client.rb +3 -4
- data/lib/howcast/client/base.rb +1 -1
- data/lib/howcast/client/video.rb +19 -19
- data/lib/howcast/logging.rb +39 -0
- data/spec/howcast/client/base_spec.rb +23 -0
- data/spec/output_capture_helper.rb +26 -0
- data/spec/spec_helper.rb +11 -215
- data/spec/string_matchers_helper.rb +22 -0
- data/spec/xml_fixtures_helper.rb +197 -0
- metadata +11 -5
- data/howcast-0.4.10.gem +0 -0
data/Rakefile
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
|
6
|
+
task :default => :spec
|
3
7
|
|
4
8
|
begin
|
5
9
|
require 'jeweler'
|
@@ -28,5 +32,10 @@ rescue LoadError
|
|
28
32
|
puts "Jeweler not available. Install it with: gem install jeweler"
|
29
33
|
end
|
30
34
|
|
35
|
+
Spec::Rake::SpecTask.new do |t|
|
36
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
37
|
+
t.spec_opts = %w(-c)
|
38
|
+
end
|
39
|
+
|
31
40
|
|
32
41
|
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.12
|
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.12"
|
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-
|
12
|
+
s.date = %q{2010-03-02}
|
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
|
@@ -31,7 +31,6 @@ Gem::Specification.new do |s|
|
|
31
31
|
"README.markdown",
|
32
32
|
"Rakefile",
|
33
33
|
"VERSION",
|
34
|
-
"howcast-0.4.10.gem",
|
35
34
|
"howcast.gemspec",
|
36
35
|
"lib/howcast.rb",
|
37
36
|
"lib/howcast/client.rb",
|
@@ -40,12 +39,16 @@ Gem::Specification.new do |s|
|
|
40
39
|
"lib/howcast/client/search.rb",
|
41
40
|
"lib/howcast/client/video.rb",
|
42
41
|
"lib/howcast/errors.rb",
|
42
|
+
"lib/howcast/logging.rb",
|
43
43
|
"spec/howcast/client/base_spec.rb",
|
44
44
|
"spec/howcast/client/category_spec.rb",
|
45
45
|
"spec/howcast/client/search_spec.rb",
|
46
46
|
"spec/howcast/client/video_spec.rb",
|
47
|
+
"spec/output_capture_helper.rb",
|
47
48
|
"spec/spec.opts",
|
48
49
|
"spec/spec_helper.rb",
|
50
|
+
"spec/string_matchers_helper.rb",
|
51
|
+
"spec/xml_fixtures_helper.rb",
|
49
52
|
"tasks/github.rake"
|
50
53
|
]
|
51
54
|
s.homepage = %q{http://github.com/howcast/howcast-gem}
|
@@ -54,11 +57,14 @@ Gem::Specification.new do |s|
|
|
54
57
|
s.rubygems_version = %q{1.3.5}
|
55
58
|
s.summary = %q{Howcast API Ruby Wrapper}
|
56
59
|
s.test_files = [
|
57
|
-
"spec/
|
58
|
-
"spec/
|
59
|
-
"spec/
|
60
|
+
"spec/output_capture_helper.rb",
|
61
|
+
"spec/xml_fixtures_helper.rb",
|
62
|
+
"spec/string_matchers_helper.rb",
|
63
|
+
"spec/spec_helper.rb",
|
64
|
+
"spec/howcast/client/base_spec.rb",
|
60
65
|
"spec/howcast/client/video_spec.rb",
|
61
|
-
"spec/
|
66
|
+
"spec/howcast/client/category_spec.rb",
|
67
|
+
"spec/howcast/client/search_spec.rb"
|
62
68
|
]
|
63
69
|
|
64
70
|
if s.respond_to? :specification_version then
|
data/lib/howcast.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
module Howcast; end
|
2
2
|
|
3
|
-
|
4
|
-
require(File.expand_path(File.join(File.dirname(__FILE__),
|
3
|
+
%w(howcast/client howcast/errors howcast/logging).each do |dependency|
|
4
|
+
require(File.expand_path(File.join(File.dirname(__FILE__), dependency)))
|
5
5
|
end
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
module Howcast
|
8
|
+
include Logging
|
9
|
+
end
|
data/lib/howcast/client.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
class Howcast::Client
|
3
3
|
end
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
require_local('howcast/client/category.rb')
|
5
|
+
%w(client/base client/video client/search client/category).each do |dependency|
|
6
|
+
require(File.expand_path(File.join(File.dirname(__FILE__), dependency)))
|
7
|
+
end
|
data/lib/howcast/client/base.rb
CHANGED
@@ -85,7 +85,7 @@ class Howcast::Client
|
|
85
85
|
relative_path_and_query = '/' + relative_path_and_query unless relative_path_and_query[0] == '/'
|
86
86
|
uri.path, uri.query = *relative_path_and_query.split('?')
|
87
87
|
h = Hpricot.XML(open(url = attach_api_key(uri)))
|
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
91
|
rescue URI::InvalidURIError, OpenURI::HTTPError
|
data/lib/howcast/client/video.rb
CHANGED
@@ -28,17 +28,17 @@ class Howcast::Client
|
|
28
28
|
@attr_accessors ||= []
|
29
29
|
@attr_accessors += args
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def attr_accessors
|
33
33
|
@attr_accessors || []
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
class Video
|
38
38
|
extend WatchAttrAccessors
|
39
|
-
attr_accessor :id, :title, :permalink, :thumbnail_url, :category_id,
|
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
|
42
42
|
# Creates a new Video object which is used to encapsulate all the attributes available
|
43
43
|
# from the Howcast Video API
|
44
44
|
#
|
@@ -47,7 +47,7 @@ class Howcast::Client
|
|
47
47
|
# * <tt>attributes</tt> -- A hash to set the various attributes of the video object
|
48
48
|
#
|
49
49
|
# === Examples
|
50
|
-
#
|
50
|
+
#
|
51
51
|
# Initialize a video with title "hello" and rating 20
|
52
52
|
# Video.new :title => "hello", :rating => 20
|
53
53
|
def initialize(attributes={})
|
@@ -55,38 +55,38 @@ class Howcast::Client
|
|
55
55
|
self.send("#{k}=", v) if self.respond_to?(k)
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
# Return true if the video contains easy step by step directions, else false
|
60
60
|
def easy_steps?
|
61
61
|
easy_steps == "true"
|
62
62
|
end
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
# Provides access to the Howcast video API.
|
66
|
-
#
|
66
|
+
#
|
67
67
|
# === Inputs
|
68
68
|
#
|
69
69
|
# * <tt>id</tt> -- The id of the video to lookup
|
70
70
|
#
|
71
71
|
# === Outputs
|
72
|
-
#
|
72
|
+
#
|
73
73
|
# Video object if the id exists or nil if the id doesn't exist or is malformed
|
74
74
|
#
|
75
75
|
# === Exceptions
|
76
|
-
#
|
76
|
+
#
|
77
77
|
# * <tt>Howcast::ApiNotFound</tt>
|
78
78
|
#
|
79
79
|
# === Examples
|
80
|
-
#
|
80
|
+
#
|
81
81
|
# Get the Howcast video with id 2
|
82
82
|
# Howcast::Client.new.video(2)
|
83
83
|
def video(id)
|
84
84
|
response = establish_connection("videos/#{id}.xml")
|
85
85
|
parse_single_xml(response.at(:video), Video)
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
# Provides access to the Howcast list videos API.
|
89
|
-
#
|
89
|
+
#
|
90
90
|
# === Inputs
|
91
91
|
#
|
92
92
|
# The options are:
|
@@ -102,17 +102,17 @@ class Howcast::Client
|
|
102
102
|
#
|
103
103
|
# === Examples
|
104
104
|
#
|
105
|
-
# Get the first page of most recent howcast studios videos.
|
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
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)}
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
def videos_url(options={})
|
116
116
|
defaults = {:page => nil, :sort => "most_recent", :filter => "howcast_studios", :category_id => nil}
|
117
117
|
options = defaults.update(options)
|
118
118
|
"videos/#{options[:sort]}/#{options[:filter]}#{"/#{options[:category_id]}" if options[:category_id]}#{"/#{options[:page]}" if options[:page]}.xml"
|
@@ -0,0 +1,39 @@
|
|
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
|
+
require 'logger'
|
24
|
+
module Howcast::Logging
|
25
|
+
def self.included base
|
26
|
+
super base
|
27
|
+
base.extend ClassMethods
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
def log
|
32
|
+
@logger ||= Logger.new($stdout)
|
33
|
+
end
|
34
|
+
|
35
|
+
def log= new_logger
|
36
|
+
@logger = new_logger
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -52,3 +52,26 @@ describe Howcast::Client, "base_uri" do
|
|
52
52
|
end.should raise_error(ArgumentError)
|
53
53
|
end
|
54
54
|
end
|
55
|
+
|
56
|
+
describe Howcast::Client, "logging" do
|
57
|
+
before :each do
|
58
|
+
@hc = Howcast::Client.new(:key => "myapikey")
|
59
|
+
@hc.stub!(:open).and_return(videos_xml)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should log each request by default" do
|
63
|
+
@hc.search("something")
|
64
|
+
captured_output.join('').should match(/Established connection/)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should be easy to make it less verbose" do
|
68
|
+
original_log_level = Howcast.log.level
|
69
|
+
begin
|
70
|
+
Howcast.log.level = Logger::FATAL
|
71
|
+
@hc.search("something")
|
72
|
+
captured_output.join('').strip.should == ""
|
73
|
+
ensure
|
74
|
+
Howcast.log.level = original_log_level
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module OutputCaptureHelper
|
2
|
+
def start_capturing_output
|
3
|
+
return @stdout, @stderr if @old_stdout or @old_stderr
|
4
|
+
@stdout, @stderr = StringIO.new, StringIO.new
|
5
|
+
@old_stdout, @old_stderr, $stdout, $stderr = $stdout, $stderr, @stdout, @stderr
|
6
|
+
return captured_output
|
7
|
+
end
|
8
|
+
|
9
|
+
def captured_output
|
10
|
+
return *[@stdout, @stderr].map(&:string)
|
11
|
+
end
|
12
|
+
|
13
|
+
def stop_capturing_output
|
14
|
+
$stdout, $stderr, @old_stdout, @old_stderr = @old_stdout, @old_stderr, nil, nil
|
15
|
+
return captured_output
|
16
|
+
end
|
17
|
+
|
18
|
+
def capture_output &noisy_block
|
19
|
+
begin
|
20
|
+
start_capturing_output
|
21
|
+
yield @stdout, @stderr
|
22
|
+
ensure
|
23
|
+
stop_capturing_output
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,223 +7,19 @@ rescue LoadError
|
|
7
7
|
end
|
8
8
|
|
9
9
|
require File.expand_path(File.dirname(__FILE__) + "/../lib/howcast")
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + "/output_capture_helper")
|
11
|
+
require File.expand_path(File.dirname(__FILE__) + "/xml_fixtures_helper")
|
12
|
+
require File.expand_path(File.dirname(__FILE__) + "/string_matchers_helper")
|
10
13
|
|
11
14
|
|
12
|
-
def to_s_like like
|
13
|
-
simple_matcher("converts to a string like #{like.inspect}") do |candidate|
|
14
|
-
like === candidate.to_s
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def equivalent_uri string
|
19
|
-
simple_matcher("is an equivalent uri to #{string.inspect}") do |candidate|
|
20
|
-
verifier = URI.parse string
|
21
|
-
tests = [
|
22
|
-
lambda{|x|x.scheme},
|
23
|
-
lambda{|x|x.userinfo},
|
24
|
-
lambda{|x|x.port},
|
25
|
-
lambda{|x|x.path},
|
26
|
-
lambda{|x|x.query.split('&').sort},
|
27
|
-
lambda{|x|x.fragment}
|
28
|
-
]
|
29
|
-
tests.all?{|t|t.call(candidate) == t.call(verifier)}
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
15
|
Spec::Runner.configure do |config|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def blank_video_xml
|
44
|
-
<<-VID
|
45
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
46
|
-
<howcast version="0.1">
|
47
|
-
<video>
|
48
|
-
</video>
|
49
|
-
</howcast>
|
50
|
-
VID
|
51
|
-
end
|
52
|
-
|
53
|
-
def blank_guides_xml
|
54
|
-
<<-GUID
|
55
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
56
|
-
<howcast version="0.1">
|
57
|
-
<guides>
|
58
|
-
</guides>
|
59
|
-
</howcast>
|
60
|
-
GUID
|
61
|
-
end
|
62
|
-
|
63
|
-
def blank_videos_xml
|
64
|
-
<<-VID
|
65
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
66
|
-
<howcast version="0.1">
|
67
|
-
<videos>
|
68
|
-
</videos>
|
69
|
-
</howcast>
|
70
|
-
VID
|
71
|
-
end
|
72
|
-
|
73
|
-
def category_xml
|
74
|
-
<<-CAT
|
75
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
76
|
-
<howcast version="0.1">
|
77
|
-
<category>
|
78
|
-
<id>1255</id>
|
79
|
-
<name>General African Travel</name>
|
80
|
-
<parent-id>1584</parent-id>
|
81
|
-
<parents>
|
82
|
-
<category id="1571">Travel</category>
|
83
|
-
<category parent_id="1571" id="1584">African Travel</category>
|
84
|
-
</parents>
|
85
|
-
<subcategories>
|
86
|
-
<category>
|
87
|
-
<id>1265</id>
|
88
|
-
<name>African Travel</name>
|
89
|
-
</category>
|
90
|
-
<category>
|
91
|
-
<id>1289</id>
|
92
|
-
<name>European Travel</name>
|
93
|
-
</category>
|
94
|
-
<category>
|
95
|
-
<id>1256</id>
|
96
|
-
<name>General Travel</name>
|
97
|
-
</category>
|
98
|
-
<category>
|
99
|
-
<id>1311</id>
|
100
|
-
<name>General U.S. Travel</name>
|
101
|
-
</category>
|
102
|
-
</subcategories>
|
103
|
-
</category>
|
104
|
-
</howcast>
|
105
|
-
CAT
|
106
|
-
end
|
107
|
-
|
108
|
-
def video_xml
|
109
|
-
<<-VID
|
110
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
111
|
-
<howcast version="0.1">
|
112
|
-
<video>
|
113
|
-
<category-id>2</category-id>
|
114
|
-
<duration>22</duration>
|
115
|
-
<id>233</id>
|
116
|
-
<easy-steps>true</easy-steps>
|
117
|
-
<badges>Howcast Studios</badges>
|
118
|
-
<title>How To Do a Noble Pose</title>
|
119
|
-
<embed>
|
120
|
-
<![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=233"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.howcast.com/flash/howcast_player.swf?file=233" type="application/x-shockwave-flash" width="425" height="352" allowFullScreen="true" allowScriptAccess="always" ></embed></object>]]>
|
121
|
-
</embed>
|
122
|
-
<description>
|
123
|
-
<![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>]]>
|
124
|
-
</description>
|
125
|
-
<permalink>http://www.howcast.com/videos/233-How-To-Do-a-Noble-Pose</permalink>
|
126
|
-
<username>joekulak</username>
|
127
|
-
<thumbnail-url>http://www.howcast.com/system/thumbnails/233/Mind.How_to_Do_the_Noble_Pose_SD_xxlarge.jpg</thumbnail-url>
|
128
|
-
<views>38</views>
|
129
|
-
<rating>2.0</rating>
|
130
|
-
<created-at>#{Time.now.rfc822}</created-at>
|
131
|
-
</video>
|
132
|
-
</howcast>
|
133
|
-
VID
|
134
|
-
end
|
135
|
-
|
136
|
-
def guides_xml
|
137
|
-
<<-VID
|
138
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
139
|
-
<howcast version="0.1">
|
140
|
-
<title>Howcast - Top Favorites Howcast Written Guides </title>
|
141
|
-
<guides>
|
142
|
-
<guide>
|
143
|
-
<rating>94</rating>
|
144
|
-
<title>How To Pretend You’re a Real New Yorker</title>
|
145
|
-
<permalink>http://www.howcast.com/guides/1101-How-To-Pretend-Youre-a-Real-New-Yorker</permalink>
|
146
|
-
<id>1101</id>
|
147
|
-
<category-id>1642</category-id>
|
148
|
-
<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>
|
149
|
-
<views>2739</views>
|
150
|
-
<username>vinzfeller</username>
|
151
|
-
<created-at>2008-02-05T19:41:21-08:00</created-at>
|
152
|
-
</guide>
|
153
|
-
<guide>
|
154
|
-
<rating>96</rating>
|
155
|
-
<title>How To Look Great in Photographs</title>
|
156
|
-
<permalink>http://www.howcast.com/guides/577-How-To-Look-Great-in-Photographs</permalink>
|
157
|
-
<id>577</id>
|
158
|
-
<category-id>22</category-id>
|
159
|
-
<description>Sure, a beautiful photograph takes some skill behind the lens, but it takes a little skill in front of it, too.</description>
|
160
|
-
<views>3831</views>
|
161
|
-
<username>nicholas</username>
|
162
|
-
<created-at>2008-01-12T09:33:06-08:00</created-at>
|
163
|
-
</guide>
|
164
|
-
<guide>
|
165
|
-
<rating>98</rating>
|
166
|
-
<title>How To Make a Water Gun Alarm Clock</title>
|
167
|
-
<permalink>http://www.howcast.com/guides/866-How-To-Make-a-Water-Gun-Alarm-Clock</permalink>
|
168
|
-
<id>866</id>
|
169
|
-
<category-id>1728</category-id>
|
170
|
-
<description>Having a little trouble waking up in the morning? There’s nothing like a good soaking to get you going.</description>
|
171
|
-
<views>2663</views>
|
172
|
-
<username>Howcast</username>
|
173
|
-
<created-at>2008-01-31T20:47:08-08:00</created-at>
|
174
|
-
</guide>
|
175
|
-
</guides>
|
176
|
-
</howcast>
|
177
|
-
VID
|
178
|
-
end
|
179
|
-
|
180
|
-
def videos_xml
|
181
|
-
<<-VID
|
182
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
183
|
-
<howcast version="0.1">
|
184
|
-
<title>Howcast - Top Favorites Howcast Studios Videos </title>
|
185
|
-
<videos>
|
186
|
-
<video>
|
187
|
-
<rating>94</rating>
|
188
|
-
<title>How To Pretend You’re a Real New Yorker</title>
|
189
|
-
<permalink>http://www.howcast.com/videos/1101-How-To-Pretend-Youre-a-Real-New-Yorker</permalink>
|
190
|
-
<id>1101</id>
|
191
|
-
<category-id>1642</category-id>
|
192
|
-
<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>
|
193
|
-
<thumbnail-url>http://www.howcast.com/system/thumbnails/1101/ppn_feller_real_newyorker_sd_medium.jpg</thumbnail-url>
|
194
|
-
<views>2739</views>
|
195
|
-
<username>vinzfeller</username>
|
196
|
-
<duration>203</duration>
|
197
|
-
<created-at>2008-02-05T19:41:21-08:00</created-at>
|
198
|
-
</video>
|
199
|
-
<video>
|
200
|
-
<rating>96</rating>
|
201
|
-
<title>How To Look Great in Photographs</title>
|
202
|
-
<permalink>http://www.howcast.com/videos/577-How-To-Look-Great-in-Photographs</permalink>
|
203
|
-
<id>577</id>
|
204
|
-
<category-id>22</category-id>
|
205
|
-
<description>Sure, a beautiful photograph takes some skill behind the lens, but it takes a little skill in front of it, too.</description>
|
206
|
-
<thumbnail-url>http://www.howcast.com/system/thumbnails/577/Arts.How_to_Look_Great_in_Photographs_SD_medium.jpg</thumbnail-url>
|
207
|
-
<views>3831</views>
|
208
|
-
<username>nicholas</username>
|
209
|
-
<duration>156</duration>
|
210
|
-
<created-at>2008-01-12T09:33:06-08:00</created-at>
|
211
|
-
</video>
|
212
|
-
<video>
|
213
|
-
<rating>98</rating>
|
214
|
-
<title>How To Make a Water Gun Alarm Clock</title>
|
215
|
-
<permalink>http://www.howcast.com/videos/866-How-To-Make-a-Water-Gun-Alarm-Clock</permalink>
|
216
|
-
<id>866</id>
|
217
|
-
<category-id>1728</category-id>
|
218
|
-
<description>Having a little trouble waking up in the morning? There’s nothing like a good soaking to get you going.</description>
|
219
|
-
<thumbnail-url>http://www.howcast.com/system/thumbnails/866/watergunthumb2_medium.jpg</thumbnail-url>
|
220
|
-
<views>2663</views>
|
221
|
-
<username>Howcast</username>
|
222
|
-
<duration>108</duration>
|
223
|
-
<created-at>2008-01-31T20:47:08-08:00</created-at>
|
224
|
-
</video>
|
225
|
-
</videos>
|
226
|
-
</howcast>
|
227
|
-
VID
|
16
|
+
config.include(OutputCaptureHelper)
|
17
|
+
config.include(XmlFixturesHelper)
|
18
|
+
config.include(StringMatchersHelper)
|
19
|
+
config.before :each do
|
20
|
+
start_capturing_output
|
21
|
+
end
|
22
|
+
config.after :each do
|
23
|
+
stop_capturing_output
|
228
24
|
end
|
229
25
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module StringMatchersHelper
|
2
|
+
def to_s_like like
|
3
|
+
simple_matcher("converts to a string like #{like.inspect}") do |candidate|
|
4
|
+
like === candidate.to_s
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def equivalent_uri string
|
9
|
+
simple_matcher("is an equivalent uri to #{string.inspect}") do |candidate|
|
10
|
+
verifier = URI.parse string
|
11
|
+
tests = [
|
12
|
+
lambda{|x|x.scheme},
|
13
|
+
lambda{|x|x.userinfo},
|
14
|
+
lambda{|x|x.port},
|
15
|
+
lambda{|x|x.path},
|
16
|
+
lambda{|x|x.query.split('&').sort},
|
17
|
+
lambda{|x|x.fragment}
|
18
|
+
]
|
19
|
+
tests.all?{|t|t.call(candidate) == t.call(verifier)}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
module XmlFixturesHelper
|
2
|
+
def invalid_api_key_xml
|
3
|
+
<<-INVALID
|
4
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
5
|
+
<howcast version="0.1">
|
6
|
+
<error>Invalid API Key</error>
|
7
|
+
</howcast>
|
8
|
+
INVALID
|
9
|
+
end
|
10
|
+
|
11
|
+
def blank_video_xml
|
12
|
+
<<-VID
|
13
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
14
|
+
<howcast version="0.1">
|
15
|
+
<video>
|
16
|
+
</video>
|
17
|
+
</howcast>
|
18
|
+
VID
|
19
|
+
end
|
20
|
+
|
21
|
+
def blank_guides_xml
|
22
|
+
<<-GUID
|
23
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
24
|
+
<howcast version="0.1">
|
25
|
+
<guides>
|
26
|
+
</guides>
|
27
|
+
</howcast>
|
28
|
+
GUID
|
29
|
+
end
|
30
|
+
|
31
|
+
def blank_videos_xml
|
32
|
+
<<-VID
|
33
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
34
|
+
<howcast version="0.1">
|
35
|
+
<videos>
|
36
|
+
</videos>
|
37
|
+
</howcast>
|
38
|
+
VID
|
39
|
+
end
|
40
|
+
|
41
|
+
def category_xml
|
42
|
+
<<-CAT
|
43
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
44
|
+
<howcast version="0.1">
|
45
|
+
<category>
|
46
|
+
<id>1255</id>
|
47
|
+
<name>General African Travel</name>
|
48
|
+
<parent-id>1584</parent-id>
|
49
|
+
<parents>
|
50
|
+
<category id="1571">Travel</category>
|
51
|
+
<category parent_id="1571" id="1584">African Travel</category>
|
52
|
+
</parents>
|
53
|
+
<subcategories>
|
54
|
+
<category>
|
55
|
+
<id>1265</id>
|
56
|
+
<name>African Travel</name>
|
57
|
+
</category>
|
58
|
+
<category>
|
59
|
+
<id>1289</id>
|
60
|
+
<name>European Travel</name>
|
61
|
+
</category>
|
62
|
+
<category>
|
63
|
+
<id>1256</id>
|
64
|
+
<name>General Travel</name>
|
65
|
+
</category>
|
66
|
+
<category>
|
67
|
+
<id>1311</id>
|
68
|
+
<name>General U.S. Travel</name>
|
69
|
+
</category>
|
70
|
+
</subcategories>
|
71
|
+
</category>
|
72
|
+
</howcast>
|
73
|
+
CAT
|
74
|
+
end
|
75
|
+
|
76
|
+
def video_xml
|
77
|
+
<<-VID
|
78
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
79
|
+
<howcast version="0.1">
|
80
|
+
<video>
|
81
|
+
<category-id>2</category-id>
|
82
|
+
<duration>22</duration>
|
83
|
+
<id>233</id>
|
84
|
+
<easy-steps>true</easy-steps>
|
85
|
+
<badges>Howcast Studios</badges>
|
86
|
+
<title>How To Do a Noble Pose</title>
|
87
|
+
<embed>
|
88
|
+
<![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=233"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.howcast.com/flash/howcast_player.swf?file=233" type="application/x-shockwave-flash" width="425" height="352" allowFullScreen="true" allowScriptAccess="always" ></embed></object>]]>
|
89
|
+
</embed>
|
90
|
+
<description>
|
91
|
+
<![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>]]>
|
92
|
+
</description>
|
93
|
+
<permalink>http://www.howcast.com/videos/233-How-To-Do-a-Noble-Pose</permalink>
|
94
|
+
<username>joekulak</username>
|
95
|
+
<thumbnail-url>http://www.howcast.com/system/thumbnails/233/Mind.How_to_Do_the_Noble_Pose_SD_xxlarge.jpg</thumbnail-url>
|
96
|
+
<views>38</views>
|
97
|
+
<rating>2.0</rating>
|
98
|
+
<created-at>#{Time.now.rfc822}</created-at>
|
99
|
+
</video>
|
100
|
+
</howcast>
|
101
|
+
VID
|
102
|
+
end
|
103
|
+
|
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
|
+
def videos_xml
|
149
|
+
<<-VID
|
150
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
151
|
+
<howcast version="0.1">
|
152
|
+
<title>Howcast - Top Favorites Howcast Studios Videos </title>
|
153
|
+
<videos>
|
154
|
+
<video>
|
155
|
+
<rating>94</rating>
|
156
|
+
<title>How To Pretend You’re a Real New Yorker</title>
|
157
|
+
<permalink>http://www.howcast.com/videos/1101-How-To-Pretend-Youre-a-Real-New-Yorker</permalink>
|
158
|
+
<id>1101</id>
|
159
|
+
<category-id>1642</category-id>
|
160
|
+
<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>
|
161
|
+
<thumbnail-url>http://www.howcast.com/system/thumbnails/1101/ppn_feller_real_newyorker_sd_medium.jpg</thumbnail-url>
|
162
|
+
<views>2739</views>
|
163
|
+
<username>vinzfeller</username>
|
164
|
+
<duration>203</duration>
|
165
|
+
<created-at>2008-02-05T19:41:21-08:00</created-at>
|
166
|
+
</video>
|
167
|
+
<video>
|
168
|
+
<rating>96</rating>
|
169
|
+
<title>How To Look Great in Photographs</title>
|
170
|
+
<permalink>http://www.howcast.com/videos/577-How-To-Look-Great-in-Photographs</permalink>
|
171
|
+
<id>577</id>
|
172
|
+
<category-id>22</category-id>
|
173
|
+
<description>Sure, a beautiful photograph takes some skill behind the lens, but it takes a little skill in front of it, too.</description>
|
174
|
+
<thumbnail-url>http://www.howcast.com/system/thumbnails/577/Arts.How_to_Look_Great_in_Photographs_SD_medium.jpg</thumbnail-url>
|
175
|
+
<views>3831</views>
|
176
|
+
<username>nicholas</username>
|
177
|
+
<duration>156</duration>
|
178
|
+
<created-at>2008-01-12T09:33:06-08:00</created-at>
|
179
|
+
</video>
|
180
|
+
<video>
|
181
|
+
<rating>98</rating>
|
182
|
+
<title>How To Make a Water Gun Alarm Clock</title>
|
183
|
+
<permalink>http://www.howcast.com/videos/866-How-To-Make-a-Water-Gun-Alarm-Clock</permalink>
|
184
|
+
<id>866</id>
|
185
|
+
<category-id>1728</category-id>
|
186
|
+
<description>Having a little trouble waking up in the morning? There’s nothing like a good soaking to get you going.</description>
|
187
|
+
<thumbnail-url>http://www.howcast.com/system/thumbnails/866/watergunthumb2_medium.jpg</thumbnail-url>
|
188
|
+
<views>2663</views>
|
189
|
+
<username>Howcast</username>
|
190
|
+
<duration>108</duration>
|
191
|
+
<created-at>2008-01-31T20:47:08-08:00</created-at>
|
192
|
+
</video>
|
193
|
+
</videos>
|
194
|
+
</howcast>
|
195
|
+
VID
|
196
|
+
end
|
197
|
+
end
|
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.12
|
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-
|
13
|
+
date: 2010-03-02 00:00:00 -08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -48,7 +48,6 @@ files:
|
|
48
48
|
- README.markdown
|
49
49
|
- Rakefile
|
50
50
|
- VERSION
|
51
|
-
- howcast-0.4.10.gem
|
52
51
|
- howcast.gemspec
|
53
52
|
- lib/howcast.rb
|
54
53
|
- lib/howcast/client.rb
|
@@ -57,12 +56,16 @@ files:
|
|
57
56
|
- lib/howcast/client/search.rb
|
58
57
|
- lib/howcast/client/video.rb
|
59
58
|
- lib/howcast/errors.rb
|
59
|
+
- lib/howcast/logging.rb
|
60
60
|
- spec/howcast/client/base_spec.rb
|
61
61
|
- spec/howcast/client/category_spec.rb
|
62
62
|
- spec/howcast/client/search_spec.rb
|
63
63
|
- spec/howcast/client/video_spec.rb
|
64
|
+
- spec/output_capture_helper.rb
|
64
65
|
- spec/spec.opts
|
65
66
|
- spec/spec_helper.rb
|
67
|
+
- spec/string_matchers_helper.rb
|
68
|
+
- spec/xml_fixtures_helper.rb
|
66
69
|
- tasks/github.rake
|
67
70
|
has_rdoc: true
|
68
71
|
homepage: http://github.com/howcast/howcast-gem
|
@@ -93,8 +96,11 @@ signing_key:
|
|
93
96
|
specification_version: 3
|
94
97
|
summary: Howcast API Ruby Wrapper
|
95
98
|
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
|
96
103
|
- spec/howcast/client/base_spec.rb
|
104
|
+
- spec/howcast/client/video_spec.rb
|
97
105
|
- spec/howcast/client/category_spec.rb
|
98
106
|
- spec/howcast/client/search_spec.rb
|
99
|
-
- spec/howcast/client/video_spec.rb
|
100
|
-
- spec/spec_helper.rb
|
data/howcast-0.4.10.gem
DELETED
Binary file
|