tenderlove-vimeo 1.3.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.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,18 @@
1
+ == 0.2.2, released 2009-04-21
2
+
3
+ * Removed CGI escapes. Vimeo should be handling them on their end.
4
+
5
+ == 0.2.1, released 2009-01-06
6
+
7
+ * Last version was missing files.
8
+
9
+ == 0.2.0, released 2009-01-06
10
+
11
+ * Major re-factor of each request method.
12
+ * Separated the simple and advanced APIs into their own modules.
13
+ * Added some documentation.
14
+ * Updated the README.
15
+
16
+ == 0.1.2, released 2008-10-26
17
+
18
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Matt Hooks
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,27 @@
1
+ CHANGELOG.rdoc
2
+ LICENSE
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ VERSION.yml
7
+ lib/vimeo.rb
8
+ lib/vimeo/advanced.rb
9
+ lib/vimeo/advanced/auth.rb
10
+ lib/vimeo/advanced/base.rb
11
+ lib/vimeo/advanced/contact.rb
12
+ lib/vimeo/advanced/group.rb
13
+ lib/vimeo/advanced/person.rb
14
+ lib/vimeo/advanced/test.rb
15
+ lib/vimeo/advanced/upload.rb
16
+ lib/vimeo/advanced/video.rb
17
+ lib/vimeo/simple.rb
18
+ lib/vimeo/simple/activity.rb
19
+ lib/vimeo/simple/album.rb
20
+ lib/vimeo/simple/base.rb
21
+ lib/vimeo/simple/channel.rb
22
+ lib/vimeo/simple/clip.rb
23
+ lib/vimeo/simple/group.rb
24
+ lib/vimeo/simple/user.rb
25
+ test/advanced/test_upload.rb
26
+ test/test_helper.rb
27
+ vimeo.gemspec
data/README.rdoc ADDED
@@ -0,0 +1,171 @@
1
+ = Vimeo API Gem
2
+
3
+ * http://github.com/matthooks/vimeo
4
+
5
+ This gem implements a full-featured ruby interface for the Vimeo API.
6
+
7
+ Vimeo's API documentation is, in my opinion, pretty poor. I've done my best to implement all the functions that are described {here}[http://vimeo.com/api-docs/advanced-api-docs.html]. There are some extra functions described {here}[http://vimeo.com/api/sandbox], but I can't be 100% sure what the correct parameters are for each method, so I'm going to omit them for the time being.
8
+
9
+ == Install
10
+
11
+ If you haven't already, add github's gem server to your sources:
12
+
13
+ gem sources -a http://gems.github.com
14
+
15
+ Then, it's as easy as:
16
+
17
+ sudo gem install matthooks-vimeo
18
+
19
+ Add the gem plugin to your Rails project by adding the following to your @environment.rb@ file:
20
+
21
+ config.gem "matthooks-vimeo", :lib => "vimeo"
22
+
23
+ == Use
24
+
25
+ There are two modules:
26
+
27
+ Vimeo::Simple
28
+ Vimeo::Advanced
29
+
30
+ == Simple API
31
+
32
+ The wrapper for the Simple API consists of the following classes and methods:
33
+
34
+ === Vimeo::Simple::User
35
+
36
+ Vimeo::Simple::User.info(username)
37
+ Vimeo::Simple::User.clips(username)
38
+ Vimeo::Simple::User.likes(username)
39
+ Vimeo::Simple::User.appears_in(username)
40
+ Vimeo::Simple::User.all_clips(username)
41
+ Vimeo::Simple::User.subscriptions(username)
42
+ Vimeo::Simple::User.albums(username)
43
+ Vimeo::Simple::User.channels(username)
44
+ Vimeo::Simple::User.groups(username)
45
+ Vimeo::Simple::User.contacts_clips(username)
46
+ Vimeo::Simple::User.contacts_like(username)
47
+
48
+ === Vimeo::Simple::Clip
49
+
50
+ Vimeo::Simple::Clip.info(video_id)
51
+
52
+ === Vimeo::Simple::Activity
53
+
54
+ Vimeo::Simple::Activity.user_did(username)
55
+ Vimeo::Simple::Activity.happened_to_user(username)
56
+ Vimeo::Simple::Activity.contacts_did(username)
57
+ Vimeo::Simple::Activity.happened_to_contacts(username)
58
+ Vimeo::Simple::Activity.everyone_did(username)
59
+
60
+ === Vimeo::Simple::Group
61
+
62
+ Vimeo::Simple::Group.clips(groupname)
63
+ Vimeo::Simple::Group.users(groupname)
64
+ Vimeo::Simple::Group.info(groupname)
65
+
66
+ === Vimeo::Simple::Channel
67
+
68
+ Vimeo::Simple::Channel.clips(channelname)
69
+ Vimeo::Simple::Channel.info(channelname)
70
+
71
+ === Vimeo::Simple::Album
72
+
73
+ Vimeo::Simple::Album.clips(album_id)
74
+ Vimeo::Simple::Album.info(album_id)
75
+
76
+ == Advanced API
77
+
78
+ The classes in Vimeo::Advanced must be instantiated with an your application's api key and secret. For example,
79
+
80
+ vimeo_video = Vimeo::Advanced::Video.new("api_key", "secret")
81
+
82
+ Then you can make calls on the instance:
83
+
84
+ vimeo_video.get_list("matthooks", :page => 2, :per_page => 50)
85
+
86
+ The wrapper for the Advanced API consists of the following classes and methods:
87
+
88
+ === Vimeo::Advanced::Auth
89
+
90
+ get_token(frob)
91
+ get_frob
92
+ check_token(auth_token)
93
+
94
+ === Vimeo::Advanced::Test
95
+
96
+ echo(options={})
97
+ null(auth_token)
98
+ login(auth_token)
99
+
100
+ === Vimeo::Advanced::Video
101
+
102
+ get_list(user_id, options={ :page => 1, :per_page => 25, :full_response => 0 })
103
+ get_uploaded_list(user_id, options={ :page => 1, :per_page => 25, :full_response => 0, :auth_token => nil })
104
+ get_appears_in_list(user_id, options={ :page => 1, :per_page => 25, :full_response => 0, :auth_token => nil })
105
+ get_subscriptions_list(user_id, options={ :page => 1, :per_page => 25, :full_response => 0, :auth_token => nil })
106
+ get_list_by_tag(tag, options={ :page => 1, :per_page => 25, :full_response => 0, :auth_token => nil })@
107
+ get_like_list(user_id, options={ :page => 1, :per_page => 25, :full_response => 0, :auth_token => nil })@
108
+ get_contacts_list(user_id, options={ :page => 1, :per_page => 25, :full_response => 0, :auth_token => nil })
109
+ get_contacts_like_list(user_id, options={ :page => 1, :per_page => 25, :full_response => 0, :auth_token => nil })
110
+ search(q, options={ :page => 1, :per_page => 25, :full_response => 0, :auth_token => nil })
111
+ get_info(video_id, auth_token=nil)
112
+ delete(video_id, auth_token)
113
+ get_thumbnail_url(video_id, size=100)
114
+ set_title(video_id, title, auth_token)
115
+ set_caption(video_id, caption, auth_token)
116
+ set_favorite(video_id, favorite, auth_token)
117
+ add_tags(video_id, tags, auth_token)
118
+ remove_tag(video_id, tag_id, auth_token)
119
+ clear_tags(video_id, auth_token)
120
+ add_cast(video_id, user_id, auth_token, options={})
121
+ get_cast(video_id, auth_token=nil)
122
+ remove_cast(video_id, user_id, auth_token)
123
+ set_privacy(video_id, privacy, auth_token)
124
+ get_comments_list(video_id)
125
+ add_comment(video_id, comment_text, auth_token, options={})
126
+ delete_comment(video_id, comment_id, auth_token)
127
+ edit_comment(video_id, comment_id, comment_text, auth_token)
128
+
129
+ === Vimeo::Advanced::Person
130
+
131
+ find_by_user_name(username)
132
+ find_by_email(find_email)
133
+ get_info(user_id)
134
+ get_portrait_url(user_id, options={})
135
+ add_contact(user_id, auth_token)
136
+ remove_contact(user_id, auth_token)
137
+ get_upload_status(user_id, auth_token)
138
+ add_subscription(user_id, type, auth_token)
139
+ remove_subscription(user_id, type, auth_token)
140
+
141
+ === Vimeo::Advanced::Contact
142
+
143
+ get_list(user_id)
144
+
145
+ === Vimeo::Advanced::Group
146
+
147
+ get_members(group_id)
148
+
149
+ === Vimeo::Advanced::Upload
150
+
151
+ get_upload_ticket(auth_token)
152
+ check_upload_status(ticket_id, auth_token)
153
+
154
+ == Todo
155
+
156
+ * Implement options that allow you to specify a format (xml, json, PHP). Right now this is slightly complicated by the fact that Vimeo returns text/html for json and not application/json, so HTTParty can't auto-detect the content-type.
157
+ * Better initialize method for the advanced api that takes the auth_token into account.
158
+ * Define a method that returns the correct form URL for uploading videos.
159
+ * video_set_privacy needs the ability to specify users.
160
+ * Some methods are not implemented by vimeo or don't seem to work.
161
+ * Input verification? The alternative is to just let vimeo handle it.
162
+ * May need to escape input in several cases
163
+ * More re-factoring.
164
+ * Tests
165
+
166
+ == Thanks to
167
+
168
+ * {HTTParty}[http://github.com/jnunemaker/httparty/tree/master]: Easily one of the best tools I have used since I started using Ruby.
169
+ * {Jeweler}[http://github.com/technicalpickles/jeweler/tree/master]: Great tool for creating gems for github.
170
+
171
+ === Copyright (c) 2008 Matt Hooks. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.spec('vimeo') do
7
+ developer 'Matt Hooks', "matthooks@gmail.com"
8
+ self.readme_file = 'README.rdoc'
9
+ self.history_file = 'CHANGELOG.rdoc'
10
+ self.extra_rdoc_files = FileList['*.rdoc']
11
+ self.extra_deps = [['jnunemaker-httparty', '>= 0.2.6']]
12
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 1
4
+ :minor: 2
@@ -0,0 +1,36 @@
1
+ module Vimeo
2
+ module Advanced
3
+
4
+ class Auth < Vimeo::Advanced::Base
5
+ # Obtains an authorization token.
6
+ def get_token(frob)
7
+ sig_options = {
8
+ :frob => frob,
9
+ :method => "vimeo.auth.getToken"
10
+ }
11
+
12
+ make_request sig_options
13
+ end
14
+
15
+ # Obtains a frob.
16
+ # Used for desktop based authentication.
17
+ def get_frob
18
+ sig_options = { :method => "vimeo.auth.getFrob" }
19
+
20
+ make_request sig_options
21
+ end
22
+
23
+ # Tests the validity of an authorization token.
24
+ def check_token(auth_token)
25
+ sig_options = {
26
+ :auth_token => auth_token,
27
+ :method => "vimeo.auth.checkToken"
28
+ }
29
+
30
+ make_request sig_options
31
+ end
32
+
33
+ end
34
+
35
+ end # Advanced
36
+ end # Vimeo
@@ -0,0 +1,66 @@
1
+ module Vimeo
2
+ module Advanced
3
+
4
+ class Base
5
+ include HTTParty
6
+ base_uri 'vimeo.com'
7
+
8
+ # TODO: Pass an auth token, if you've already got one
9
+ # TODO: implement format_options
10
+ # Requires your API key and secret phrase.
11
+ # The API key and secret are prepended to every request.
12
+ def initialize(api_key, secret, format_options={})
13
+ @auth = { :api_key => api_key }
14
+ @secret = secret
15
+ end
16
+
17
+ # Generates a link that allows a user to authorize
18
+ # your web application to use the advanced API
19
+ def login_link(perms, frob)
20
+ api_sig = generate_api_sig :perms => perms
21
+ "http://vimeo.com/services/auth/?api_key=#{@auth[:api_key]}&perms=#{perms}&frob=#{frob}&api_sig=#{api_sig}"
22
+ end
23
+
24
+ # TODO: Implement a function that returns the correct upload URL
25
+
26
+ # Generates the proper API signature for a file upload.
27
+ def upload_sig(ticket_id, auth_token)
28
+ sig_options = {
29
+ :ticket_id => ticket_id,
30
+ :auth_token => auth_token
31
+ }
32
+
33
+ generate_api_sig sig_options
34
+ end
35
+
36
+ private
37
+
38
+ # Generates a MD5 hashed API signature for Advanced API requests
39
+ def generate_api_sig(options={})
40
+ # Every request requires the api_key parameter
41
+ options.merge! @auth
42
+ # Keys must be sorted alphabetically
43
+ api_sig = options.sort { |a, b| a.to_s <=> b.to_s }.join
44
+ Digest::MD5.hexdigest("#{@secret}#{api_sig}")
45
+ end
46
+
47
+ def query(sig_options, api_sig)
48
+ sig_options.merge :api_key => @auth[:api_key], :api_sig => api_sig
49
+ end
50
+
51
+ def make_request(sig_options)
52
+ api_sig = generate_api_sig sig_options
53
+ self.class.post "/api/rest", :query => query(sig_options, api_sig)
54
+ end
55
+
56
+ def rand_string len
57
+ chars = ('a'..'z').to_a + ('A'..'Z').to_a
58
+ string = ''
59
+ 1.upto(len) { |i| string << chars[rand(chars.size-1)] }
60
+ string
61
+ end
62
+
63
+ end # Base
64
+
65
+ end # Advanced
66
+ end # Vimeo
@@ -0,0 +1,18 @@
1
+ module Vimeo
2
+ module Advanced
3
+
4
+ class Contact < Vimeo::Advanced::Base
5
+
6
+ def get_list(user_id)
7
+ sig_options = {
8
+ :user_id => user_id,
9
+ :method => "vimeo.contacts.getList"
10
+ }
11
+
12
+ make_request sig_options
13
+ end
14
+
15
+ end
16
+
17
+ end # Advanced
18
+ end # Vimeo
@@ -0,0 +1,19 @@
1
+ module Vimeo
2
+ module Advanced
3
+
4
+ class Group < Vimeo::Advanced::Base
5
+
6
+ # Fixme: Only takes group_id as int, not group name
7
+ def get_members(group_id)
8
+ sig_options = {
9
+ :group_id => group_id,
10
+ :method => "vimeo.groups.getMembers"
11
+ }
12
+
13
+ make_request sig_options
14
+ end
15
+
16
+ end
17
+
18
+ end # Advanced
19
+ end # Vimeo
@@ -0,0 +1,105 @@
1
+ module Vimeo
2
+ module Advanced
3
+
4
+ class Person < Vimeo::Advanced::Base
5
+
6
+ def find_by_user_name(username)
7
+ sig_options = {
8
+ :username => username,
9
+ :method => "vimeo.people.findByUserName"
10
+ }
11
+
12
+ make_request sig_options
13
+ end
14
+
15
+ def find_by_email(find_email)
16
+ sig_options = {
17
+ :find_email => find_email,
18
+ :method => "vimeo.people.findByEmail"
19
+ }
20
+
21
+ make_request sig_options
22
+ end
23
+
24
+ def get_info(user_id)
25
+ sig_options = {
26
+ :user_id => user_id,
27
+ :method => "vimeo.people.getInfo"
28
+ }
29
+
30
+ make_request sig_options
31
+ end
32
+
33
+ # TODO: This seems to be returning nil from Vimeo... not implemented?
34
+ def get_portrait_url(user_id, options={})
35
+ size = options[:size]
36
+
37
+ sig_options = {
38
+ :user_id => user_id,
39
+ :method => "vimeo.people.getPortraitUrl"
40
+ }
41
+ sig_options.merge! :size => size unless size.nil?
42
+
43
+ make_request sig_options
44
+ end
45
+
46
+ # TODO: Not working on Vimeo's side
47
+ def add_contact(user_id, auth_token)
48
+ sig_options = {
49
+ :user_id => user_id,
50
+ :auth_token => auth_token,
51
+ :method => "vimeo.people.addContact"
52
+ }
53
+
54
+ make_request sig_options
55
+ end
56
+
57
+ # TODO: Not working on Vimeo's side
58
+ def remove_contact(user_id, auth_token)
59
+ sig_options = {
60
+ :user_id => user_id,
61
+ :auth_token => auth_token,
62
+ :method => "vimeo.people.removeContact"
63
+ }
64
+
65
+ make_request sig_options
66
+ end
67
+
68
+ def get_upload_status(user_id, auth_token)
69
+ sig_options = {
70
+ :user_id => user_id,
71
+ :auth_token => auth_token,
72
+ :method => "vimeo.people.getUploadStatus"
73
+ }
74
+
75
+ make_request sig_options
76
+ end
77
+
78
+ # TODO: Verify input for type?
79
+ def add_subscription(user_id, type, auth_token)
80
+ sig_options = {
81
+ :user_id => user_id,
82
+ :type => type,
83
+ :auth_token => auth_token,
84
+ :method => "vimeo.people.addSubscription"
85
+ }
86
+
87
+ make_request sig_options
88
+ end
89
+
90
+ # TODO: Verify input for type?
91
+ def remove_subscription(user_id, type, auth_token)
92
+ sig_options = {
93
+ :user_id => user_id,
94
+ :type => type,
95
+ :auth_token => auth_token,
96
+ :method => "vimeo.people.removeSubscription"
97
+ }
98
+
99
+ make_request sig_options
100
+ end
101
+
102
+ end
103
+
104
+ end # Advanced
105
+ end # Vimeo
@@ -0,0 +1,40 @@
1
+ module Vimeo
2
+ module Advanced
3
+
4
+ class Test < Vimeo::Advanced::Base
5
+ # An echo test. Echoes all parameters.
6
+ # Options can be anything except method, api_key,
7
+ # and api_sig -- if any of these options are
8
+ # present they will be overwritten by the proper
9
+ # values.
10
+ def echo(options={})
11
+ options.merge!(:method => "vimeo.test.echo")
12
+ api_sig = generate_api_sig options
13
+ options.merge!(:api_sig => api_sig)
14
+ self.class.post("/api/rest", :query => options)
15
+ end
16
+
17
+ # A null test.
18
+ def null(auth_token)
19
+ sig_options = {
20
+ :auth_token => auth_token,
21
+ :method => "vimeo.test.null"
22
+ }
23
+
24
+ make_request sig_options
25
+ end
26
+
27
+ # Tests if the user associated to this token
28
+ # is able to make authenticated calls.
29
+ def login(auth_token)
30
+ sig_options = {
31
+ :auth_token => auth_token,
32
+ :method => "vimeo.test.login"
33
+ }
34
+
35
+ make_request sig_options
36
+ end
37
+ end
38
+
39
+ end # Advanced
40
+ end # Vimeo
@@ -0,0 +1,104 @@
1
+ require 'webrick/httputils'
2
+
3
+ module Vimeo
4
+ module Advanced
5
+
6
+ class Upload < Vimeo::Advanced::Base
7
+
8
+ def get_upload_ticket(auth_token)
9
+ sig_options = {
10
+ :auth_token => auth_token,
11
+ :method => "vimeo.videos.getUploadTicket"
12
+ }
13
+
14
+ make_request sig_options
15
+ end
16
+
17
+ def check_upload_status(ticket_id, auth_token)
18
+ sig_options = {
19
+ :ticket_id => ticket_id,
20
+ :auth_token => auth_token,
21
+ :method => "vimeo.videos.checkUploadStatus"
22
+ }
23
+
24
+ make_request sig_options
25
+ end
26
+
27
+ ###
28
+ # Upload +file+ to vimeo with +ticket_id+ and +auth_token+
29
+ def upload file, ticket_id, auth_token
30
+ boundary = rand_string 20
31
+
32
+ enctype = "multipart/form-data; boundary=#{boundary}"
33
+
34
+ file_part = file_to_multipart(file)
35
+
36
+ params = {
37
+ :auth_token => auth_token,
38
+ :ticket_id => ticket_id
39
+ }
40
+ params[:api_sig] = generate_api_sig params
41
+
42
+ data = (params.map { |k,v| param_to_multipart(k,v) } +
43
+ [file_part]
44
+ ).map { |part|
45
+ "--#{boundary}\r\n#{part}"
46
+ }.join + "--#{boundary}--\r\n"
47
+
48
+ uri = URI.parse('http://vimeo.com/services/upload')
49
+
50
+ http_ctx = Net::HTTP.new(uri.host, uri.port)
51
+ request = Net::HTTP::Post.new(uri.request_uri)
52
+ request['Content-Type'] = enctype
53
+ request['Content-Length'] = data.size.to_s
54
+ http_ctx.request(request, data)
55
+ end
56
+
57
+ def signature_for_file_upload(ticket_id, auth_token)
58
+ sig_options = {
59
+ :ticket_id => ticket_id,
60
+ :auth_token => auth_token
61
+ }
62
+ generate_api_sig sig_options
63
+ end
64
+
65
+ private
66
+ def mime_value_quote(str)
67
+ str.to_s.gsub(/(["\r\\])/){|s| '\\' + s}
68
+ end
69
+
70
+ def param_to_multipart name, value
71
+ "Content-Disposition: form-data; name=\"#{mime_value_quote(name)}\"" +
72
+ "\r\n#{value}\r\n"
73
+ end
74
+
75
+ def file_to_multipart file
76
+ file_name = File.basename(file)
77
+
78
+ headers = nil
79
+
80
+ File.open(file, 'rb') { |fh|
81
+
82
+ mime_type = WEBrick::HTTPUtils.mime_type(
83
+ file,
84
+ WEBrick::HTTPUtils::DefaultMimeTypes
85
+ )
86
+
87
+ headers = [
88
+ "Content-Disposition: form-data; name=\"" +
89
+ "#{mime_value_quote(file)}\"; " +
90
+ "filename=\"#{mime_value_quote(file_name)}\"",
91
+ "Content-Transfer-Encoding: binary",
92
+ ]
93
+
94
+ headers << "Content-Type: #{mime_type}" if mime_type
95
+ headers << nil
96
+ headers << fh.read
97
+ }
98
+ headers.join("\r\n") + "\r\n"
99
+ end
100
+
101
+ end
102
+
103
+ end # Advanced
104
+ end # Vimeo