howcast 0.3.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 +19 -0
- data/License.txt +20 -0
- data/Manifest.txt +35 -0
- data/README.txt +30 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/lib/howcast.rb +9 -0
- data/lib/howcast/client.rb +8 -0
- data/lib/howcast/client/base.rb +154 -0
- data/lib/howcast/client/guide.rb +89 -0
- data/lib/howcast/client/search.rb +89 -0
- data/lib/howcast/client/video.rb +123 -0
- data/lib/howcast/errors.rb +8 -0
- data/lib/howcast/version.rb +20 -0
- data/log/debug.log +0 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/spec/howcast/client/base_spec.rb +14 -0
- data/spec/howcast/client/guide_spec.rb +65 -0
- data/spec/howcast/client/search_spec.rb +88 -0
- data/spec/howcast/client/video_spec.rb +109 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +167 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- data/website/index.html +114 -0
- data/website/index.txt +57 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.rhtml +48 -0
- metadata +101 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Howcast::Client, "initialize" do
|
4
|
+
it "should create a client object with all the inputted attributes" do
|
5
|
+
client = Howcast::Client.new :key => "myapikey"
|
6
|
+
client.should be_instance_of(Howcast::Client)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should raise a Howcast::ApiKeyNotFound error when no key is supplied" do
|
10
|
+
lambda {
|
11
|
+
Howcast::Client.new
|
12
|
+
}.should raise_error(Howcast::ApiKeyNotFound)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Howcast::Client::Guide, "initialize" do
|
4
|
+
it "should create a guide object with all the inputted attributes" do
|
5
|
+
guide = Howcast::Client::Guide.new :title => "guide_title"
|
6
|
+
guide.title.should == 'guide_title'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should ignore inputs which are not guide attributes" do
|
10
|
+
guide = Howcast::Client::Guide.new :not_an_attribute => "value", :title => "guide_title"
|
11
|
+
guide.respond_to?(:not_an_attribute).should be_false
|
12
|
+
guide.title.should == "guide_title"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Howcast::Client, "guides" do
|
17
|
+
before do
|
18
|
+
@hc = Howcast::Client.new(:key => "myapikey")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should establish a connection with guides/most_recent/howcast_written.xml by default" do
|
22
|
+
@hc.should_receive(:open).with("http://www.howcast.com/guides/most_recent/howcast_written.xml?api_key=myapikey").and_return(guides_xml)
|
23
|
+
@hc.guides
|
24
|
+
end
|
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)
|
28
|
+
@hc.guides(:page => 2)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should establish a connection with guides/most_viewed/howcast_written.xml when :sort => most_viewed" do
|
32
|
+
@hc.should_receive(:open).with("http://www.howcast.com/guides/most_viewed/howcast_written.xml?api_key=myapikey").and_return(guides_xml)
|
33
|
+
@hc.guides(:sort => "most_viewed")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should establish a connection with guides/most_viewed/community_written.xml when :sort => most_viewed and :filter => community_written" do
|
37
|
+
@hc.should_receive(:open).with("http://www.howcast.com/guides/most_viewed/community_written.xml?api_key=myapikey").and_return(guides_xml)
|
38
|
+
@hc.guides(:sort => "most_viewed", :filter => "community_written")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should establish a connection with guides/top_rated/community_written.xml when :sort => top_rated and :filter => community_written" do
|
42
|
+
@hc.should_receive(:open).with("http://www.howcast.com/guides/top_rated/community_written.xml?api_key=myapikey").and_return(guides_xml)
|
43
|
+
@hc.guides(:sort => "top_rated", :filter => "community_written")
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should raise a Howcast::ApiNotFound if url is invalid" do
|
47
|
+
lambda {
|
48
|
+
@hc.should_receive(:open).and_raise(URI::InvalidURIError)
|
49
|
+
@hc.guides
|
50
|
+
}.should raise_error(Howcast::ApiNotFound)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return an empty array if there are no results" do
|
54
|
+
@hc.should_receive(:open).and_return(blank_guides_xml)
|
55
|
+
@hc.guides.should be_empty
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return an array of guide objects if there are some returned" do
|
59
|
+
@hc.should_receive(:open).and_return(guides_xml)
|
60
|
+
guides = @hc.guides
|
61
|
+
guides.size.should == 3
|
62
|
+
guides.first.permalink.should == "http://www.howcast.com/guides/1101-How-To-Pretend-Youre-a-Real-New-Yorker"
|
63
|
+
guides.last.permalink.should == "http://www.howcast.com/guides/866-How-To-Make-a-Water-Gun-Alarm-Clock"
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Howcast::Client, "video_search" do
|
4
|
+
before do
|
5
|
+
@hc = Howcast::Client.new(:key => "myapikey")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should establish a connection with search.xml?q=something&view=video when query is 'something'" do
|
9
|
+
@hc.should_receive(:open).with("http://www.howcast.com/search.xml?q=something&view=video&api_key=myapikey").and_return(videos_xml)
|
10
|
+
@hc.video_search("something")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should establish a connection with search.xml?q=something&view=video&page=2 when query is 'something' and :page => 2" do
|
14
|
+
@hc.should_receive(:open).with("http://www.howcast.com/search.xml?q=something&view=video&page=2&api_key=myapikey").and_return(videos_xml)
|
15
|
+
@hc.video_search("something", :page => 2)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should escape the query when esablishing the connection" do
|
19
|
+
@hc.should_receive(:open).with("http://www.howcast.com/search.xml?q=something+%26+something&view=video&api_key=myapikey").and_return(videos_xml)
|
20
|
+
@hc.video_search("something & something")
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should append mode=extended when passed in as an option" do
|
24
|
+
@hc.should_receive(:open).with("http://www.howcast.com/search.xml?q=something&view=video&mode=extended&api_key=myapikey").and_return(videos_xml)
|
25
|
+
@hc.video_search("something", :mode => :extended)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should raise a Howcast::ApiNotFound if url is invalid" do
|
29
|
+
lambda {
|
30
|
+
@hc.should_receive(:open).and_raise(URI::InvalidURIError)
|
31
|
+
@hc.video_search("something")
|
32
|
+
}.should raise_error(Howcast::ApiNotFound)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return an empty array if there are no results" do
|
36
|
+
@hc.should_receive(:open).and_return(blank_videos_xml)
|
37
|
+
@hc.video_search("something").should be_empty
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return an array of video objects if there are some returned" do
|
41
|
+
@hc.should_receive(:open).and_return(videos_xml)
|
42
|
+
videos = @hc.video_search("something")
|
43
|
+
videos.size.should == 3
|
44
|
+
videos.first.permalink.should == "http://www.howcast.com/videos/1101-How-To-Pretend-Youre-a-Real-New-Yorker"
|
45
|
+
videos.last.permalink.should == "http://www.howcast.com/videos/866-How-To-Make-a-Water-Gun-Alarm-Clock"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe Howcast::Client, "guide_search" do
|
50
|
+
before do
|
51
|
+
@hc = Howcast::Client.new(:key => "myapikey")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should establish a connection with search.xml?q=something&view=guide when query is 'something'" do
|
55
|
+
@hc.should_receive(:open).with("http://www.howcast.com/search.xml?q=something&view=guide&api_key=myapikey").and_return(guides_xml)
|
56
|
+
@hc.guide_search("something")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should establish a connection with search.xml?q=something&view=guide&page=2 when query is 'something' and :page => 2" do
|
60
|
+
@hc.should_receive(:open).with("http://www.howcast.com/search.xml?q=something&view=guide&page=2&api_key=myapikey").and_return(guides_xml)
|
61
|
+
@hc.guide_search("something", :page => 2)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should escape the query when esablishing the connection" do
|
65
|
+
@hc.should_receive(:open).with("http://www.howcast.com/search.xml?q=something+%26+something&view=guide&api_key=myapikey").and_return(guides_xml)
|
66
|
+
@hc.guide_search("something & something")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should raise a Howcast::ApiNotFound if url is invalid" do
|
70
|
+
lambda {
|
71
|
+
@hc.should_receive(:open).and_raise(URI::InvalidURIError)
|
72
|
+
@hc.guide_search("something")
|
73
|
+
}.should raise_error(Howcast::ApiNotFound)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should return an empty array if there are no results" do
|
77
|
+
@hc.should_receive(:open).and_return(blank_guides_xml)
|
78
|
+
@hc.guide_search("something").should be_empty
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should return an array of video objects if there are some returned" do
|
82
|
+
@hc.should_receive(:open).and_return(videos_xml)
|
83
|
+
videos = @hc.video_search("something")
|
84
|
+
videos.size.should == 3
|
85
|
+
videos.first.permalink.should == "http://www.howcast.com/videos/1101-How-To-Pretend-Youre-a-Real-New-Yorker"
|
86
|
+
videos.last.permalink.should == "http://www.howcast.com/videos/866-How-To-Make-a-Water-Gun-Alarm-Clock"
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Howcast::Client::Video, "initialize" do
|
4
|
+
it "should create a video object with all the inputted attributes" do
|
5
|
+
video = Howcast::Client::Video.new :title => "video_title"
|
6
|
+
video.title.should == 'video_title'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should ignore inputs which are not video attributes" do
|
10
|
+
video = Howcast::Client::Video.new :not_an_attribute => "value", :title => "video_title"
|
11
|
+
video.respond_to?(:not_an_attribute).should be_false
|
12
|
+
video.title.should == "video_title"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Howcast::Client, "video" do
|
17
|
+
before do
|
18
|
+
@hc = Howcast::Client.new(:key => "myapikey")
|
19
|
+
@hc.stub!(:open).and_return(video_xml)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should establish a connection with the correct video url" do
|
23
|
+
@hc.should_receive(:open).with("http://www.howcast.com/videos/2.xml?api_key=myapikey").and_return(video_xml)
|
24
|
+
@hc.video(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.video(2)
|
31
|
+
}.should raise_error(Howcast::ApiKeyNotFound)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return nil whenever the result xml is empty" do
|
35
|
+
@hc.stub!(:open).and_return(blank_video_xml)
|
36
|
+
@hc.video(2).should be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should set the title attribute in the video model response" do
|
40
|
+
@hc.video(2).title.should == "How To Do a Noble Pose"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should set the views attribute in the video model response" do
|
44
|
+
@hc.video(2).views.should == "38"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should set the rating attribute in the video model response" do
|
48
|
+
@hc.video(2).rating.should == "2.0"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set the description attribute in the video model response" do
|
52
|
+
@hc.video(2).description.should == "You recognize the Noble Pose as the dreaded \"sit-and-reach\" from your childhood gym class. A sample <a href=\"howcast.com\">link</a>"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should set the permalink attribute in the video model response" do
|
56
|
+
@hc.video(2).permalink.should == "http://www.howcast.com/videos/233-How-To-Do-a-Noble-Pose"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe Howcast::Client, "videos" do
|
61
|
+
before do
|
62
|
+
@hc = Howcast::Client.new(:key => "myapikey")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should establish a connection with videos/most_recent/howcast_studios.xml by default" do
|
66
|
+
@hc.should_receive(:open).with("http://www.howcast.com/videos/most_recent/howcast_studios.xml?api_key=myapikey").and_return(videos_xml)
|
67
|
+
@hc.videos
|
68
|
+
end
|
69
|
+
|
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)
|
72
|
+
@hc.videos(:page => 2)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should establish a connection with videos/most_viewed/howcast_studios.xml when :sort => most_viewed" do
|
76
|
+
@hc.should_receive(:open).with("http://www.howcast.com/videos/most_viewed/howcast_studios.xml?api_key=myapikey").and_return(videos_xml)
|
77
|
+
@hc.videos(:sort => "most_viewed")
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should establish a connection with videos/most_viewed/directors_program.xml when :sort => most_viewed and :filter => directors_program" do
|
81
|
+
@hc.should_receive(:open).with("http://www.howcast.com/videos/most_viewed/directors_program.xml?api_key=myapikey").and_return(videos_xml)
|
82
|
+
@hc.videos(:sort => "most_viewed", :filter => "directors_program")
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should establish a connection with videos/top_rated/directors_program.xml when :sort => most_viewed and :filter => directors_program" do
|
86
|
+
@hc.should_receive(:open).with("http://www.howcast.com/videos/top_rated/directors_program.xml?api_key=myapikey").and_return(videos_xml)
|
87
|
+
@hc.videos(:sort => "top_rated", :filter => "directors_program")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should raise a Howcast::ApiNotFound if url is invalid" do
|
91
|
+
lambda {
|
92
|
+
@hc.should_receive(:open).and_raise(URI::InvalidURIError)
|
93
|
+
@hc.videos
|
94
|
+
}.should raise_error(Howcast::ApiNotFound)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should return an empty array if there are no results" do
|
98
|
+
@hc.should_receive(:open).and_return(blank_videos_xml)
|
99
|
+
@hc.videos.should be_empty
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should return an array of video objects if there are some returned" do
|
103
|
+
@hc.should_receive(:open).and_return(videos_xml)
|
104
|
+
videos = @hc.videos
|
105
|
+
videos.size.should == 3
|
106
|
+
videos.first.permalink.should == "http://www.howcast.com/videos/1101-How-To-Pretend-Youre-a-Real-New-Yorker"
|
107
|
+
videos.last.permalink.should == "http://www.howcast.com/videos/866-How-To-Make-a-Water-Gun-Alarm-Clock"
|
108
|
+
end
|
109
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
ENV["RAILS_ENV"] ||= "test"
|
2
|
+
begin
|
3
|
+
require 'spec'
|
4
|
+
rescue LoadError
|
5
|
+
require 'rubygems'
|
6
|
+
require 'spec'
|
7
|
+
end
|
8
|
+
|
9
|
+
require File.expand_path(File.dirname(__FILE__) + "/../lib/howcast")
|
10
|
+
|
11
|
+
Spec::Runner.configure do |config|
|
12
|
+
def invalid_api_key_xml
|
13
|
+
<<-INVALID
|
14
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
15
|
+
<howcast version="0.1">
|
16
|
+
<error>Invalid API Key</error>
|
17
|
+
</howcast>
|
18
|
+
INVALID
|
19
|
+
end
|
20
|
+
|
21
|
+
def blank_video_xml
|
22
|
+
<<-VID
|
23
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
24
|
+
<howcast version="0.1">
|
25
|
+
<video>
|
26
|
+
</video>
|
27
|
+
</howcast>
|
28
|
+
VID
|
29
|
+
end
|
30
|
+
|
31
|
+
def blank_guides_xml
|
32
|
+
<<-GUID
|
33
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
34
|
+
<howcast version="0.1">
|
35
|
+
<guides>
|
36
|
+
</guides>
|
37
|
+
</howcast>
|
38
|
+
GUID
|
39
|
+
end
|
40
|
+
|
41
|
+
def blank_videos_xml
|
42
|
+
<<-VID
|
43
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
44
|
+
<howcast version="0.1">
|
45
|
+
<videos>
|
46
|
+
</videos>
|
47
|
+
</howcast>
|
48
|
+
VID
|
49
|
+
end
|
50
|
+
|
51
|
+
def video_xml
|
52
|
+
<<-VID
|
53
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
54
|
+
<howcast version="0.1">
|
55
|
+
<video>
|
56
|
+
<category-id>2</category-id>
|
57
|
+
<duration>22</duration>
|
58
|
+
<id>233</id>
|
59
|
+
<title>How To Do a Noble Pose</title>
|
60
|
+
<description>
|
61
|
+
<![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>]]>
|
62
|
+
</description>
|
63
|
+
<permalink>http://www.howcast.com/videos/233-How-To-Do-a-Noble-Pose</permalink>
|
64
|
+
<username>joekulak</username>
|
65
|
+
<thumbnail-url>http://www.howcast.com/system/thumbnails/233/Mind.How_to_Do_the_Noble_Pose_SD_xxlarge.jpg</thumbnail-url>
|
66
|
+
<views>38</views>
|
67
|
+
<rating>2.0</rating>
|
68
|
+
<created-at>#{Time.now.rfc822}</created-at>
|
69
|
+
</video>
|
70
|
+
</howcast>
|
71
|
+
VID
|
72
|
+
end
|
73
|
+
|
74
|
+
def guides_xml
|
75
|
+
<<-VID
|
76
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
77
|
+
<howcast version="0.1">
|
78
|
+
<title>Howcast - Top Favorites Howcast Written Guides </title>
|
79
|
+
<guides>
|
80
|
+
<guide>
|
81
|
+
<rating>94</rating>
|
82
|
+
<title>How To Pretend You’re a Real New Yorker</title>
|
83
|
+
<permalink>http://www.howcast.com/guides/1101-How-To-Pretend-Youre-a-Real-New-Yorker</permalink>
|
84
|
+
<id>1101</id>
|
85
|
+
<category-id>1642</category-id>
|
86
|
+
<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>
|
87
|
+
<views>2739</views>
|
88
|
+
<username>vinzfeller</username>
|
89
|
+
<created-at>2008-02-05T19:41:21-08:00</created-at>
|
90
|
+
</guide>
|
91
|
+
<guide>
|
92
|
+
<rating>96</rating>
|
93
|
+
<title>How To Look Great in Photographs</title>
|
94
|
+
<permalink>http://www.howcast.com/guides/577-How-To-Look-Great-in-Photographs</permalink>
|
95
|
+
<id>577</id>
|
96
|
+
<category-id>22</category-id>
|
97
|
+
<description>Sure, a beautiful photograph takes some skill behind the lens, but it takes a little skill in front of it, too.</description>
|
98
|
+
<views>3831</views>
|
99
|
+
<username>nicholas</username>
|
100
|
+
<created-at>2008-01-12T09:33:06-08:00</created-at>
|
101
|
+
</guide>
|
102
|
+
<guide>
|
103
|
+
<rating>98</rating>
|
104
|
+
<title>How To Make a Water Gun Alarm Clock</title>
|
105
|
+
<permalink>http://www.howcast.com/guides/866-How-To-Make-a-Water-Gun-Alarm-Clock</permalink>
|
106
|
+
<id>866</id>
|
107
|
+
<category-id>1728</category-id>
|
108
|
+
<description>Having a little trouble waking up in the morning? There’s nothing like a good soaking to get you going.</description>
|
109
|
+
<views>2663</views>
|
110
|
+
<username>Howcast</username>
|
111
|
+
<created-at>2008-01-31T20:47:08-08:00</created-at>
|
112
|
+
</guide>
|
113
|
+
</guides>
|
114
|
+
</howcast>
|
115
|
+
VID
|
116
|
+
end
|
117
|
+
|
118
|
+
def videos_xml
|
119
|
+
<<-VID
|
120
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
121
|
+
<howcast version="0.1">
|
122
|
+
<title>Howcast - Top Favorites Howcast Studios Videos </title>
|
123
|
+
<videos>
|
124
|
+
<video>
|
125
|
+
<rating>94</rating>
|
126
|
+
<title>How To Pretend You’re a Real New Yorker</title>
|
127
|
+
<permalink>http://www.howcast.com/videos/1101-How-To-Pretend-Youre-a-Real-New-Yorker</permalink>
|
128
|
+
<id>1101</id>
|
129
|
+
<category-id>1642</category-id>
|
130
|
+
<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>
|
131
|
+
<thumbnail-url>http://www.howcast.com/system/thumbnails/1101/ppn_feller_real_newyorker_sd_medium.jpg</thumbnail-url>
|
132
|
+
<views>2739</views>
|
133
|
+
<username>vinzfeller</username>
|
134
|
+
<duration>203</duration>
|
135
|
+
<created-at>2008-02-05T19:41:21-08:00</created-at>
|
136
|
+
</video>
|
137
|
+
<video>
|
138
|
+
<rating>96</rating>
|
139
|
+
<title>How To Look Great in Photographs</title>
|
140
|
+
<permalink>http://www.howcast.com/videos/577-How-To-Look-Great-in-Photographs</permalink>
|
141
|
+
<id>577</id>
|
142
|
+
<category-id>22</category-id>
|
143
|
+
<description>Sure, a beautiful photograph takes some skill behind the lens, but it takes a little skill in front of it, too.</description>
|
144
|
+
<thumbnail-url>http://www.howcast.com/system/thumbnails/577/Arts.How_to_Look_Great_in_Photographs_SD_medium.jpg</thumbnail-url>
|
145
|
+
<views>3831</views>
|
146
|
+
<username>nicholas</username>
|
147
|
+
<duration>156</duration>
|
148
|
+
<created-at>2008-01-12T09:33:06-08:00</created-at>
|
149
|
+
</video>
|
150
|
+
<video>
|
151
|
+
<rating>98</rating>
|
152
|
+
<title>How To Make a Water Gun Alarm Clock</title>
|
153
|
+
<permalink>http://www.howcast.com/videos/866-How-To-Make-a-Water-Gun-Alarm-Clock</permalink>
|
154
|
+
<id>866</id>
|
155
|
+
<category-id>1728</category-id>
|
156
|
+
<description>Having a little trouble waking up in the morning? There’s nothing like a good soaking to get you going.</description>
|
157
|
+
<thumbnail-url>http://www.howcast.com/system/thumbnails/866/watergunthumb2_medium.jpg</thumbnail-url>
|
158
|
+
<views>2663</views>
|
159
|
+
<username>Howcast</username>
|
160
|
+
<duration>108</duration>
|
161
|
+
<created-at>2008-01-31T20:47:08-08:00</created-at>
|
162
|
+
</video>
|
163
|
+
</videos>
|
164
|
+
</howcast>
|
165
|
+
VID
|
166
|
+
end
|
167
|
+
end
|