howkast 0.0.0

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.
@@ -0,0 +1,69 @@
1
+ require 'rubygems'
2
+ require 'yaml'
3
+ begin
4
+ require 'howkast'
5
+ rescue LoadError
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ require 'howkast'
8
+ end
9
+
10
+ # configure
11
+ Howkast::configure YAML.load File.read('.howkast')
12
+
13
+ # create instance
14
+ howcast = Howkast::API.new
15
+
16
+ # alternative instantiation
17
+ # howcast = Howkast::API.new :api_key => 'YOUR-HOWCAST-API-KEY'
18
+
19
+ # search for jujitsu how-to videos
20
+ search = howcast.search :query => 'jujitsu'
21
+
22
+ # get detail for the first video listed in the search
23
+ video_id = search.videos.first.id
24
+ video = howcast.video :id => video_id
25
+ puts video.title
26
+ puts video.embed
27
+
28
+ # find out what other videos where uploaded by the same user
29
+ username = video.username
30
+ user = howcast.user :id => username, :resource => :videos
31
+ puts user.title
32
+ user.videos.each do |video|
33
+ puts "- #{video.id}\t#{video.title}"
34
+ end
35
+
36
+ # list user's favorite videos
37
+ user = howcast.user :id => username, :resource => :favorites
38
+ puts user.title
39
+ user.videos.each do |video|
40
+ puts "- #{video.id}\t#{video.title}\t#{video.description}"
41
+ end
42
+
43
+ # list user's playlists
44
+ user = howcast.user :id => username, :resource => :playlists
45
+ puts user.title
46
+ user.playlists.each do |video|
47
+ puts "- #{video.id}\t#{video.title}"
48
+ end
49
+
50
+ # list available categories
51
+ categories = howcast.categories
52
+ categories.each do |category|
53
+ puts "#{category.id}\t#{category.name}"
54
+ end
55
+
56
+ # get details about a category
57
+ category = howcast.category :id => categories.first.id
58
+ puts category.name
59
+ category.subcategories.each do |category|
60
+ puts "- #{category.id}\t#{category.name}"
61
+ end
62
+
63
+ # list the videos in a playlist
64
+ playlist = howcast.playlist :id => '4261'
65
+ puts playlist.title
66
+ puts playlist.description
67
+ playlist.videos.each do |video|
68
+ puts "- #{video.id}\t#{video.title}"
69
+ end
@@ -0,0 +1,120 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Howkast::API::service" do
4
+ before :all do
5
+ @config ||= YAML.load File.read(File.expand_path(File.dirname(__FILE__) + '/../../.howkast'))
6
+ Howkast::configure @config
7
+ @howcast = Howkast::API.new
8
+ end
9
+
10
+ it "should be able to list supported services" do
11
+ services = Howkast::API.services
12
+ services.should be_an_instance_of Array
13
+ services.should_not be_empty
14
+ end
15
+
16
+ it "should provide implementation for the services it supports" do
17
+ services = Howkast::API.services
18
+ services.should be_an_instance_of Array
19
+ services.should_not be_empty
20
+ howcast = Howkast::API.new
21
+ services.each do |service|
22
+ howcast.should respond_to service
23
+ end
24
+ end
25
+
26
+ # service :category,
27
+ # processor: :categories,
28
+ # options: { :required => :id }
29
+ it "should raise an error if the category contract is broken" do
30
+ ->{ @howcast.category :id => :id }.should_not raise_error ArgumentError
31
+
32
+ ->{ @howcast.category }.should raise_error ArgumentError
33
+ ->{ @howcast.category :x => :x }.should raise_error ArgumentError
34
+ ->{ @howcast.category :x }.should raise_error ArgumentError
35
+ ->{ @howcast.category :x, { :x => :x } }.should raise_error ArgumentError
36
+ ->{ @howcast.category :x, { :id => :id } }.should raise_error ArgumentError
37
+ end
38
+
39
+ # service :categories
40
+ it "should raise an error if the categories contract is broken" do
41
+ ->{ @howcast.categories }.should_not raise_error ArgumentError
42
+
43
+ ->{ @howcast.categories :x }.should raise_error ArgumentError
44
+ ->{ @howcast.categories :x => :x }.should raise_error ArgumentError
45
+ ->{ @howcast.categories :x, { :x => :x } }.should raise_error ArgumentError
46
+ ->{ @howcast.categories :x => :x }.should raise_error ArgumentError
47
+ end
48
+
49
+ # service :search,
50
+ # options: { :required => :query, :optional => { :view => :video } }
51
+ it "should raise an error if the search contract is broken" do
52
+ ->{ @howcast.search :query =>:query }.should_not raise_error ArgumentError
53
+
54
+ ->{ @howcast.search }.should raise_error ArgumentError
55
+ ->{ @howcast.search :x =>:x }.should raise_error ArgumentError
56
+ ->{ @howcast.search :x }.should raise_error ArgumentError
57
+ ->{ @howcast.search :x, { :x => :x } }.should raise_error ArgumentError
58
+ ->{ @howcast.search :x, { :query => :query } }.should raise_error ArgumentError
59
+ end
60
+
61
+ # service :playlist,
62
+ # processor: :playlists,
63
+ # options: { :required => :id }
64
+ it "should raise an error if the playlist contract is broken" do
65
+ ->{ @howcast.playlist :id => :id }.should_not raise_error ArgumentError
66
+
67
+ ->{ @howcast.playlist }.should raise_error ArgumentError
68
+ ->{ @howcast.playlist :x }.should raise_error ArgumentError
69
+ ->{ @howcast.playlist :x, { :x => :x } }.should raise_error ArgumentError
70
+ ->{ @howcast.playlist :x, { :id => :id } }.should raise_error ArgumentError
71
+ end
72
+
73
+
74
+ # service :video,
75
+ # processor: :videos,
76
+ # options: { :required => :id }
77
+ it "should raise an error if the video contract is broken" do
78
+ ->{ @howcast.video :id => :id }.should_not raise_error ArgumentError
79
+
80
+ ->{ @howcast.video }.should raise_error ArgumentError
81
+ ->{ @howcast.video :x => :x }.should raise_error ArgumentError
82
+ ->{ @howcast.video :x }.should raise_error ArgumentError
83
+ ->{ @howcast.video :x, { :x => :x } }.should raise_error ArgumentError
84
+ ->{ @howcast.video :x, { :id => :id } }.should raise_error ArgumentError
85
+ end
86
+
87
+
88
+ # service :videos,
89
+ # options: { :required => [ :sort, :filter ],
90
+ # :optional => [ :category, :page ] }
91
+ it "should raise an error if the videos contract is broken" do
92
+ ->{ @howcast.videos :sort => :sort, :filter => :filter }.should_not raise_error ArgumentError
93
+ ->{ @howcast.videos :sort => :sort, :filter => :filter, :category => :category }.should_not raise_error ArgumentError
94
+ ->{ @howcast.videos :sort => :sort, :filter => :filter, :page => :page }.should_not raise_error ArgumentError
95
+ ->{ @howcast.videos :sort => :sort, :filter => :filter, :category => :category, :page => :page }.should_not raise_error ArgumentError
96
+
97
+ ->{ @howcast.videos :sort => :sort }.should raise_error ArgumentError
98
+ ->{ @howcast.videos :filter => :filter }.should raise_error ArgumentError
99
+ ->{ @howcast.videos }.should raise_error ArgumentError
100
+ ->{ @howcast.videos :x }.should raise_error ArgumentError
101
+ ->{ @howcast.videos :x => :x }.should raise_error ArgumentError
102
+ ->{ @howcast.videos :x, { :x => :x } }.should raise_error ArgumentError
103
+ ->{ @howcast.videos :x, { :sort => :sort, :filter => :filter } }.should raise_error ArgumentError
104
+ end
105
+
106
+ # service :user,
107
+ # processor: :users,
108
+ # options: { :required => [ :id, :resource ] }
109
+ it "should raise an error if the user contract is broken" do
110
+ ->{ @howcast.user :id => :id, :resource => :resource }.should_not raise_error ArgumentError
111
+
112
+ ->{ @howcast.user :id => :id }.should raise_error ArgumentError
113
+ ->{ @howcast.user :resource => :resource }.should raise_error ArgumentError
114
+ ->{ @howcast.user }.should raise_error ArgumentError
115
+ ->{ @howcast.user :x }.should raise_error ArgumentError
116
+ ->{ @howcast.user :x => :x }.should raise_error ArgumentError
117
+ ->{ @howcast.user :x, { :x => :x } }.should raise_error ArgumentError
118
+ ->{ @howcast.user :x, { :id => :id, :resource => :resource } }.should raise_error ArgumentError
119
+ end
120
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Howkast::API" do
4
+ API_KEY1 = '6c6d1613339399efd0bc74fe12b14dd370b3ac76'
5
+ API_KEY2 = 'bec946eaa53dc4e0527b28917f318fcd70b3ac76'
6
+
7
+ before :all do
8
+ @config ||= YAML.load File.read(File.expand_path(File.dirname(__FILE__) + '/../../.howkast'))
9
+ Howkast::configure @config
10
+ @howcast = Howkast::API.new
11
+ end
12
+
13
+ it "should honor configuration" do
14
+ Howkast::configure :api_key => API_KEY1
15
+ howcast = Howkast::API.new
16
+ howcast.configuration.api_key.should eql API_KEY1
17
+ end
18
+
19
+ it "should be able to override configuration" do
20
+ Howkast::configure :api_key => API_KEY1
21
+ howcast = Howkast::API.new api_key: API_KEY2
22
+ howcast.configuration.api_key.should eql API_KEY2
23
+ end
24
+ end
@@ -0,0 +1,73 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Howkast::Model" do
4
+ before :each do
5
+ @foo = 'Foo'
6
+ @foo_data = { x: 1, y: 2, z: 3 }
7
+
8
+ @bar = 'Bar'
9
+ @bar_data = { x: 1, y: 2, z: 3, foo: @foo_data }
10
+
11
+ @zoo = 'Zoo'
12
+ @zoo_data = { x: 1, y: 2, z: 3, foo: @foo_data, bar: @bar_data }
13
+ end
14
+
15
+ it "should be able to create model types" do
16
+ klass = Howkast::Model.synthesize(@foo, @foo_data)
17
+ klass.should eql Howkast::Model::Foo
18
+ klass.public_instance_methods.should include :instance_attributes
19
+ end
20
+
21
+ it "should be able to create model instances" do
22
+ klass = Howkast::Model.synthesize(@foo, @foo_data)
23
+ foo = klass.new(self, @foo_data)
24
+ foo.should be_an_instance_of Howkast::Model::Foo
25
+ foo.should respond_to :instance_attributes
26
+ @foo_data.keys.each do |attr|
27
+ foo.should respond_to attr
28
+ end
29
+ end
30
+
31
+ it "should be able to append more attributes to an existing model type" do
32
+ klass = Howkast::Model.synthesize(@foo, @foo_data)
33
+ foo = klass.new(self, @foo_data)
34
+ foo.should be_an_instance_of Howkast::Model::Foo
35
+ @foo_data.keys.each do |attr|
36
+ foo.should respond_to attr
37
+ end
38
+
39
+ klass = Howkast::Model.synthesize(@foo, @bar_data)
40
+ foo = klass.new(self, { })
41
+ foo.should be_an_instance_of Howkast::Model::Foo
42
+ @foo_data.merge(@bar_data).keys.each do |attr|
43
+ foo.should respond_to attr
44
+ end
45
+ end
46
+
47
+ it "should be able to parse a String value and convert it to an appropriate type" do
48
+ Howkast::Model.parse("String").should be_an_instance_of String
49
+ Howkast::Model.parse("1x").should be_an_instance_of String
50
+ Howkast::Model.parse("1").should be_an_instance_of Fixnum
51
+ Howkast::Model.parse("11111111").should be_an_instance_of Fixnum
52
+ Howkast::Model.parse("+1").should be_an_instance_of Fixnum
53
+ Howkast::Model.parse("-1").should be_an_instance_of Fixnum
54
+ Howkast::Model.parse("0.1x").should be_an_instance_of Float
55
+ Howkast::Model.parse("0.1").should be_an_instance_of Float
56
+ Howkast::Model.parse("0.111111").should be_an_instance_of Float
57
+ Howkast::Model.parse("+0.1").should be_an_instance_of Float
58
+ Howkast::Model.parse("-0.1").should be_an_instance_of Float
59
+ Howkast::Model.parse("+0.1111111").should be_an_instance_of Float
60
+ Howkast::Model.parse("-0.1111111").should be_an_instance_of Float
61
+ Howkast::Model.parse("true").should be_an_instance_of TrueClass
62
+ Howkast::Model.parse("True").should be_an_instance_of TrueClass
63
+ Howkast::Model.parse("TRUE").should be_an_instance_of TrueClass
64
+ Howkast::Model.parse("false").should be_an_instance_of FalseClass
65
+ Howkast::Model.parse("False").should be_an_instance_of FalseClass
66
+ Howkast::Model.parse("FALSE").should be_an_instance_of FalseClass
67
+ Howkast::Model.parse("Sun, 3 Jul 2008 20:00:39 -0700").should be_an_instance_of Time
68
+ Howkast::Model.parse("Mon, 14 Jul 2008 20:00:39 -0700").should be_an_instance_of Time
69
+ Howkast::Model.parse("Wed Dec 29 12:21:32 PST 2010").should be_an_instance_of Time
70
+ Howkast::Model.parse("Wed Dec 1 12:21:32 PST 2010").should be_an_instance_of Time
71
+ Howkast::Model.parse("Wed Dec 7 12:21:32 PST 2010").should be_an_instance_of Time
72
+ end
73
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Howkast::Processor::Categories" do
4
+ before :all do
5
+ @config ||= YAML.load File.read(File.expand_path(File.dirname(__FILE__) + '/../../../.howkast'))
6
+ Howkast::configure @config
7
+ @howcast = Howkast::API.new
8
+ end
9
+
10
+ it "should raise an error if given a non-valid category ID" do
11
+ ->{ @howcast.category :id => '9999999999999999999999999' }.should \
12
+ raise_error Howkast::Error::RequestError
13
+ end
14
+
15
+ it "should return a Category object given a valid category ID" do
16
+ category = @howcast.category :id => 1105
17
+ category.should be_an_instance_of Howkast::Model::Category
18
+ end
19
+
20
+ it "should return an array of Category objects" do
21
+ list = @howcast.categories
22
+ list.should be_an_instance_of Array
23
+ list.each do |entry|
24
+ entry.should be_an_instance_of Howkast::Model::Category
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Howkast::Processor::Playlists" do
4
+ before :all do
5
+ @config ||= YAML.load File.read(File.expand_path(File.dirname(__FILE__) + '/../../../.howkast'))
6
+ Howkast::configure @config
7
+ @howcast = Howkast::API.new
8
+ end
9
+
10
+ it "should raise an error if given a non-valid playlist ID" do
11
+ ->{ @howcast.playlist :id => '9999999999999999999999999' }.should \
12
+ raise_error Howkast::Error::RequestError
13
+ end
14
+
15
+ it "should return a Playlist object given a valid playlist ID" do
16
+ playlist = @howcast.playlist :id => 4261
17
+ playlist.should be_an_instance_of Howkast::Model::Playlist
18
+ playlist.should respond_to :videos
19
+ list = playlist.videos
20
+ list.should be_an_instance_of Array
21
+ list.should_not be_empty
22
+ list.each do |entry|
23
+ entry.should be_an_instance_of Howkast::Model::Video
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Howkast::Processor::Search" do
4
+ before :all do
5
+ @config ||= YAML.load File.read(File.expand_path(File.dirname(__FILE__) + '/../../../.howkast'))
6
+ Howkast::configure @config
7
+ @howcast = Howkast::API.new
8
+ end
9
+
10
+ it "should always return a Search object" do
11
+ %w{ howcast kreektrebano }.each do |query|
12
+ search = @howcast.search :query => query
13
+ search.should be_an_instance_of Howkast::Model::Search
14
+ search.should respond_to :videos
15
+ search.should respond_to :title
16
+ (search.title =~ /#{query}/u).should_not be nil
17
+ list = search.videos
18
+ list.should be_an_instance_of Array
19
+ list.should_not be_empty if query == 'howcast'
20
+ list.should be_empty if query == 'kreektrebano'
21
+ list.each do |entry|
22
+ entry.should be_an_instance_of Howkast::Model::Video
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Howkast::Processor::Users" do
4
+ before :all do
5
+ @config ||= YAML.load File.read(File.expand_path(File.dirname(__FILE__) + '/../../../.howkast'))
6
+ Howkast::configure @config
7
+ @howcast = Howkast::API.new
8
+ @resources = %w{ videos favorites playlists }
9
+ end
10
+
11
+ it "should raise an error if given a non-valid user ID" do
12
+ ->{ @howcast.user :id => 'kreektrebano', :resource => :videos }.should \
13
+ raise_error Howkast::Error::RequestError
14
+ end
15
+
16
+ it "should raise an error if given an unrecognized resource" do
17
+ ->{ @howcast.user :id => 'jurisgalang', :resource => :jurisgalang }.should \
18
+ raise_error Howkast::Error::RequestError
19
+ end
20
+
21
+ it "should return a User object given a valid user ID" do
22
+ user = @howcast.user :id => 'jurisgalang', :resource => :videos
23
+ user.should be_an_instance_of Howkast::Model::User
24
+ end
25
+
26
+ it "should return a User object with the appropriate resource attribute" do
27
+ @resources.each do |resource|
28
+ user = @howcast.user :id => 'howcast', :resource => resource
29
+ user.should be_an_instance_of Howkast::Model::User
30
+
31
+ examine = ->(resource, attribute, model) do
32
+ list = user.send(attribute)
33
+ list.should be_an_instance_of Array
34
+ list.should_not be_empty
35
+ list.each do |entry|
36
+ entry.should be_an_instance_of model
37
+ end
38
+ end
39
+
40
+ args = case resource
41
+ when 'videos', 'favorites'
42
+ [resource, :videos, Howkast::Model::Video]
43
+ when 'playlists'
44
+ [resource, :playlists, Howkast::Model::Playlist]
45
+ else
46
+ fail 'dude, you messed up!'
47
+ end
48
+ examine[*args]
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe "Howkast::Processor::Videos" do
4
+ before :all do
5
+ @config ||= YAML.load File.read(File.expand_path(File.dirname(__FILE__) + '/../../../.howkast'))
6
+ Howkast::configure @config
7
+ @howcast = Howkast::API.new
8
+ end
9
+
10
+ it "should raise an error if given a non-valid video ID" do
11
+ ->{ @howcast.video :id => '9999999999999999999999999' }.should \
12
+ raise_error Howkast::Error::RequestError
13
+ end
14
+
15
+ it "should return a Video object given a valid video ID" do
16
+ video = @howcast.video :id => 6570
17
+ video.should be_an_instance_of Howkast::Model::Video
18
+ end
19
+
20
+ it "should return an array of Video objects" do
21
+ categories = @howcast.categories.map{ |category| category.permalink.split('/').last }
22
+ categories = categories[0 .. 9]
23
+ categories << nil
24
+ categories.each do |category|
25
+ %w{ most_viewed most_recent top_rated }.each do |sort|
26
+ %w{ all howcast_studios }.each do |filter|
27
+ opts = { :sort => sort, :filter => filter }
28
+ opts[:category] = category unless category.nil?
29
+ list = @howcast.videos opts
30
+ list.should be_an_instance_of Array
31
+ list.each do |entry|
32
+ entry.should be_an_instance_of Howkast::Model::Video
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end