dm 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a3efcb21d39dea62767ab57939fa1f54091e9532
4
+ data.tar.gz: 4770202bbf71cd96f77723b99453f42017e6f515
5
+ SHA512:
6
+ metadata.gz: c436618bebbaa74e240177b71983ba5c81c0b2efbb526f90d32fca6091f64d16dd9c67862dbfb4ab504dbf8b4484c8b458716973199b2e81dada7a258f1313d8
7
+ data.tar.gz: c366cb0e09b3db776d24157604cf6b2a3af00f7f679ef14ea829ee22af71f85030c878106d417e289b038cf69523153a540f7ff4a8e02ab33d488003687a1d50
@@ -0,0 +1,20 @@
1
+ Copyright 2014 claudiob
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.
@@ -0,0 +1,211 @@
1
+ Dm
2
+ ======
3
+
4
+ Dm lets you interact with many resources provided by DailyMotion API V3.
5
+
6
+ [![Build Status](https://travis-ci.org/claudiob/dm.png?branch=master)](https://travis-ci.org/claudiob/dm)
7
+ [![Code Climate](https://codeclimate.com/github/claudiob/dm.png)](https://codeclimate.com/github/claudiob/dm)
8
+ [![Coverage Status](https://coveralls.io/repos/claudiob/dm/badge.png)](https://coveralls.io/r/claudiob/dm)
9
+ [![Dependency Status](https://gemnasium.com/claudiob/dm.png)](https://gemnasium.com/claudiob/dm)
10
+
11
+
12
+ ```ruby
13
+ channel = Dm::DailyMotionResource.new url: 'dailymotion.com/remhq'
14
+ channel.id #=> 'UC7eaRqtonpyiYw0Pns0Au_g'
15
+ channel.title #=> "remhq"
16
+ channel.description #=> "R.E.M.'s Official DailyMotion Channel"
17
+ ```
18
+
19
+ ```ruby
20
+ video = Dm::DailyMotionResource.new url: 'youtu.be/Kd5M17e7Wek'
21
+ video.id #=> 'Kd5M17e7Wek'
22
+ video.title #=> "R.E.M. - Tongue (Video)"
23
+ video.description #=> "© 2006 WMG\nTongue (Video)"
24
+ ```
25
+
26
+ ```ruby
27
+ account = Dm::DailyMotionAccount.new auth_params
28
+ account.email #=> 'user@google.com'
29
+ ```
30
+
31
+ ```ruby
32
+ account = Dm::DailyMotionAccount.new auth_params
33
+ account.perform! :like, :video, 'Kd5M17e7Wek' # => adds 'Tongue' to your 'Liked videos'
34
+ account.perform! :subscribe_to, :channel, 'UC7eaRqtonpyiYw0Pns0Au_g' # => subscribes to R.E.M.’s channel
35
+ ```
36
+
37
+ The full documentation is available at [rubydoc.info](http://rubydoc.info/github/claudiob/dm/master/frames).
38
+
39
+ Available classes
40
+ =================
41
+
42
+ Dm exposes three different resources provided by DailyMotion API V3:
43
+ DailyMotion Accounts, DailyMotion Accounts and DailyMotion Resources.
44
+
45
+ DailyMotion accounts
46
+ ---------------
47
+
48
+ Use `Dm::DailyMotionAccount` to send and retrieve data to DailyMotion,
49
+ impersonating an existing DailyMotion account. Available methods:
50
+
51
+ * `email`: returns the email of a DailyMotion account
52
+ * `name`: returns the name of a DailyMotion account
53
+
54
+ These methods require user authentication (see below).
55
+
56
+ DailyMotion accounts
57
+ ----------------
58
+
59
+ Use `Dm::DailyMotionAccount` to send and retrieve data to DailyMotion,
60
+ impersonating an existing DailyMotion account. Available methods:
61
+
62
+ * `perform!`: executes promotion actions such as: liking a video, subscribing to a channel
63
+
64
+ These methods require user authentication (see below).
65
+
66
+ DailyMotion resources
67
+ -----------------
68
+
69
+ Use `Dm::DailyMotionResource` to retrieve read-only information about
70
+ public DailyMotion channels and videos. Available methods:
71
+
72
+ * `id`: returns the unique identifier of a DailyMotion channel/video
73
+ * `title`: returns the title of a DailyMotion channel/video
74
+ * `description`: returns the description of a DailyMotion channel/video
75
+ * `thubmnail_url`: returns the URL of the thumbnail of a DailyMotion channel/video
76
+
77
+ These methods require do not require user authentication.
78
+
79
+ Authentication
80
+ ==============
81
+
82
+ In order to use Dm you must register your app in the [DailyMotion Developers Console](https://console.developers.google.com):
83
+
84
+ 1. Create a new app and enable access to DailyMotion+ API and DailyMotion Data API V3
85
+ 1. Generate a new OAuth client ID (web application) and write down the `client ID` and `client secret`
86
+ 1. Generate a new Public API access key (for server application) and write down the `server key`
87
+
88
+ Run the following command to make these tokens available to Dm:
89
+
90
+ ```ruby
91
+ require 'dm'
92
+ Dm.authenticate_with client_id: '...', client_secret: '...', server_key: '...'
93
+ ```
94
+
95
+ replacing the ellipses with the values from the DailyMotion Developers Console.
96
+
97
+ For actions that impersonate a DailyMotion or DailyMotion account, you also need to
98
+ obtain authorization from the owner of the account you wish to impersonate:
99
+
100
+ 1. In your web site, add a link to the DailyMotion's OAuth login page. The URL is:
101
+
102
+ ```ruby
103
+ Dm::DailyMotionAccount.oauth_url(url) # to impersonate a DailyMotion Account
104
+ Dm::DailyMotionAccount.oauth_url(url) # to impersonate a DailyMotion Account
105
+ ```
106
+
107
+ 1. Upon authorization, the user is redirected to the URL passed as an argument, with an extra 'code' query parameter which can be used to impersonate the account:
108
+
109
+ ```ruby
110
+ account = Dm::DailyMotionAccount.new(code: code, redirect_uri: url) # to impersonate a DailyMotion Account
111
+ account = Dm::DailyMotionAccount.new(code: code, redirect_uri: url) # to impersonate a DailyMotion Account
112
+ ```
113
+
114
+ 1. To prevent the user from having to authorize the app every time, store the account’s refresh_token in your database:
115
+
116
+ ```ruby
117
+ refresh_token = account.credentials[:refresh_token] # Store to your DB
118
+ ```
119
+
120
+ 1. To impersonate an account that has already authorized your app, just use the refresh_token:
121
+
122
+ ```ruby
123
+ account = Dm::DailyMotionAccount.new(refresh_token: refresh_token) # to impersonate a DailyMotion Account
124
+ account = Dm::DailyMotionAccount.new(refresh_token: refresh_token) # to impersonate a DailyMotion Account
125
+ ```
126
+
127
+ Remember that the redirect URL you use in the app must also be registered in
128
+ the DailyMotion Developers Console.
129
+ Also, remember to set a Product name for your app in the DailyMotion Developers
130
+ Console, under API & Auth > Consent screen.
131
+
132
+ How to install
133
+ ==============
134
+
135
+ To install on your system, run
136
+
137
+ gem install dm
138
+
139
+ To use inside a bundled Ruby project, add this line to the Gemfile:
140
+
141
+ gem 'dm', '~> 0.1.0'
142
+
143
+ The dm gem follows [Semantic Versioning](http://semver.org).
144
+ Any new release that is fully backward-compatible bumps the *patch* version (0.0.x).
145
+ Any new version that breaks compatibility bumps the *minor* version (0.x.0)
146
+
147
+ Indicating the full version in your Gemfile (*major*.*minor*.*patch*) guarantees
148
+ that your project won’t occur in any error when you `bundle update` and a new
149
+ version of Dm is released.
150
+
151
+ Why you should use Dm…
152
+ --------------------------
153
+
154
+ … and not [dailymotion_it](https://github.com/kylejginavan/dailymotion_it)?
155
+ Because dailymotion_it does not support DailyMotion API V3 and the previous version
156
+ has already been deprecated by DailyMotion and will soon be dropped.
157
+
158
+ … and not [DailyMotion Api Client](https://github.com/google/google-api-ruby-client)?
159
+ Because DailyMotion Api Client is poorly coded, poorly documented and adds many
160
+ dependencies, bloating the size of your project.
161
+
162
+ … and not your own code? Because Dm is fully tested, well documented,
163
+ has few dependencies and helps you forget about the burden of dealing with
164
+ DailyMotion API!
165
+
166
+ How to test
167
+ ===========
168
+
169
+ To run the tests, you must give the test app permissions to access your
170
+ DailyMotion and DailyMotion accounts. They are free, so feel free to create a fake one.
171
+
172
+ 1. Run the following commands in a ruby session:
173
+
174
+ ```ruby
175
+ require 'dm'
176
+ Dm::DailyMotionAccount.oauth_url # => "https://accounts.google.com/o..."
177
+ ```
178
+
179
+ 1. Copy the last URL in a browser, and accept the terms. You will be redirected to a URL like http://example.com/?code=ABCDE
180
+
181
+ 1. Copy the `code` parameter (ABCDE in the example above) and run:
182
+
183
+ ```ruby
184
+ account = Dm::DailyMotionAccount.new code: 'ABCDE'
185
+ account.credentials[:refresh_token]
186
+ ```
187
+
188
+ 1. Copy the token returned by the last command (something like 1AUJZh2x1...) and store it in an environment variable before running the test suite:
189
+
190
+ ```ruby
191
+ export GOOGOL_TEST_GOOGLE_REFRESH_TOKEN="1AUJZh2x1..."
192
+ ```
193
+
194
+ 1. Repeat all the steps above replacing DailyMotionAccount with DailyMotionAccount to authorize access to your DailyMotion account:
195
+
196
+ ```ruby
197
+ export GOOGOL_TEST_YOUTUBE_REFRESH_TOKEN="2B6T5x23..."
198
+ ```
199
+
200
+ 1. Finally run the tests running `rspec` or `rake`. If you prefer not to set environment variables, pass the refresh token in the same line:
201
+
202
+ ```ruby
203
+ GOOGOL_TEST_GOOGLE_REFRESH_TOKEN="1AUJZh2x1..." GOOGOL_TEST_YOUTUBE_REFRESH_TOKEN="2B6T5x23..." rspec
204
+ ```
205
+
206
+ How to contribute
207
+ =================
208
+
209
+ Don’t hesitate to send code comments, issues or pull requests through GitHub!
210
+
211
+ All feedback is appreciated. A [dm](http://en.wikipedia.org/wiki/Dm) of thanks! :)
@@ -0,0 +1,3 @@
1
+ require 'dm/google_account'
2
+ require 'dm/dailymotion_account'
3
+ require 'dm/dailymotion_resource'
@@ -0,0 +1,96 @@
1
+ require 'uri'
2
+ require 'cgi'
3
+ require 'dm/client_tokens'
4
+ require 'dm/requestable'
5
+
6
+ module Dm
7
+ # Provides methods to authenticate as an account (either DailyMotion or DailyMotion).
8
+ module Authenticable
9
+ include ClientTokens
10
+ include Requestable
11
+
12
+ # Initialize an object with either an authorization code or a refresh token
13
+ #
14
+ # @see https://developers.google.com/accounts/docs/OAuth2
15
+ #
16
+ # @param [Hash] attrs Authentication credentials to access the account
17
+ # @option attrs [String] :code The OAuth2 authorization code
18
+ # @option attrs [String] :redirect_url The page to redirect after the OAuth2 page
19
+ # @option attrs [String] :refresh_token The refresh token for offline access
20
+ def initialize(attrs = {})
21
+ @code = attrs[:code]
22
+ @refresh_token = attrs[:refresh_token]
23
+ @redirect_url = attrs.fetch :redirect_url, 'http://example.com/'
24
+ end
25
+
26
+ # Return the authorization credentials of an account for this app.
27
+ #
28
+ # @see ...
29
+ #
30
+ # @return [Hash]
31
+ # * :client_id [String] ...
32
+ # * :client_secret [String] ...
33
+ # * ...
34
+ def credentials
35
+ @credentials ||= request! method: :post,
36
+ host: 'https://accounts.google.com',
37
+ path: '/o/oauth2/token',
38
+ body: credentials_params,
39
+ valid_if: -> response, body {response.code == '200'}
40
+ end
41
+
42
+ private
43
+
44
+ # Provides the credentials to access DailyMotion API as an authorized user.
45
+ #
46
+ # There are ways to do this:
47
+ # - For first-time users (who do not have a refresh token but only an
48
+ # authorization code): the code is submitted to DailyMotion to obtain an
49
+ # access token (to use immediately) and a refresh_token
50
+ # - For existing users (who have a refresh token): the refresh token is
51
+ # submitted to DailyMotion to obtain a new access token
52
+ def credentials_params
53
+ if @refresh_token
54
+ {grant_type: :refresh_token, refresh_token: @refresh_token}
55
+ else
56
+ {grant_type: :authorization_code, code: @code, redirect_uri: @redirect_url}
57
+ end.merge client_id: client_id, client_secret: client_secret
58
+ end
59
+
60
+ def self.included(base)
61
+ base.extend ClassMethods
62
+ end
63
+
64
+ module ClassMethods
65
+ include ClientTokens
66
+ # Returns the URL for users to authorize this app to access their account
67
+ #
68
+ # @param [String] redirect_url The page to redirect after the OAuth2 page
69
+ #
70
+ # @return [String] URL of the OAuth2 Authorization page.
71
+ #
72
+ # @note The redirect_url *must* match one of the redirect URLs whitelisted
73
+ # for the app in the DailyMotion Developers Console
74
+ #
75
+ # @see https://console.developers.google.com
76
+ def oauth_url(redirect_url = 'http://example.com/')
77
+ params = {
78
+ client_id: client_id,
79
+ scope: oauth_scopes.join(' '),
80
+ redirect_uri: redirect_url,
81
+ response_type: :code,
82
+ access_type: :offline,
83
+ approval_prompt: :force
84
+ }
85
+ q = params.map{|k,v| "#{CGI.escape k.to_s}=#{CGI.escape v.to_s}"}.join '&'
86
+ args = {host: 'accounts.google.com', path: '/o/oauth2/auth', query: q}
87
+ URI::HTTPS.build(args).to_s
88
+ end
89
+
90
+ # Set the scopes to grant access to an account.
91
+ # This method is meant to be overridden.
92
+ def oauth_scopes
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,22 @@
1
+ module Dm
2
+ module ClientTokens
3
+ @@client_id = '461491672627.apps.googleusercontent.com'
4
+ @@client_secret = 'qXRBFZyL9X0NHMEJ_9ItefC3'
5
+
6
+ def client_id
7
+ @@client_id
8
+ end
9
+
10
+ def client_secret
11
+ @@client_secret
12
+ end
13
+
14
+ def self.client_id=(client_id)
15
+ @@client_id = client_id
16
+ end
17
+
18
+ def self.client_secret=(client_secret)
19
+ @@client_secret = client_secret
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,74 @@
1
+ require 'dm/authenticable'
2
+
3
+ module Dm
4
+ # Provides read & write access to a DailyMotion (or DailyMotion+) account.
5
+ #
6
+ # @example Retrieve the email and given name of a DailyMotion account:
7
+ # * Set up two pages: one with a link to authenticate, one to redirect to
8
+ # * In the first page, add a link to the authentication page:
9
+ #
10
+ # Dm::DailyMotionAccount.oauth_url(redirect_url)
11
+ #
12
+ # * The user authenticates and lands on the second page, with an extra +code+ query parameter
13
+ # * Use the authorization code to initialize the DailyMotionAccount and retrieve information:
14
+ #
15
+ # account = Dm::DailyMotionAccount.new code: code, redirect_url: redirect_url
16
+ # account.email # => 'user@example.com'
17
+ # account.given_name # => 'Example user'
18
+ #
19
+ class DailyMotionAccount
20
+ include Authenticable
21
+ # Return the profile info of a DailyMotion account in OpenID Connect format.
22
+ #
23
+ # @see https://developers.google.com/+/api/latest/people/getOpenIdConnect
24
+ #
25
+ # @return [Hash]
26
+ # * :id [String] The ID of the authenticated account
27
+ # * :email [String] The account’s email address.
28
+ # * :verified_email [String] Boolean flag which is true if the email address is verified.
29
+ # * :name [String] The account’s full name.
30
+ # * :given_name [String] The account’s given (first) name.
31
+ # * :family_name [String] The account’s family (last) name.
32
+ # * :link [String] The URL of the account’s profile page.
33
+ # * :picture [String] The URL of the account’s profile picture.
34
+ # * :gender [String] The account’s gender
35
+ # * :locale [String] The account’s preferred locale.
36
+ # * :hd [String] The hosted domain name for the accounts’s DailyMotion Apps.
37
+ def info
38
+ @info ||= request! method: :get,
39
+ auth: credentials[:access_token],
40
+ host: 'https://www.googleapis.com',
41
+ path: '/oauth2/v2/userinfo',
42
+ valid_if: -> response, body {response.code == '200'}
43
+ end
44
+
45
+ # Define a method to return each attribute of the profile separately.
46
+ #
47
+ # @macro [attach] attribute.name
48
+ # @method $1()
49
+ # Return the $1 attribute of the DailyMotion Account.
50
+ #
51
+ def self.attribute(name)
52
+ define_method(name) { info[name] }
53
+ end
54
+
55
+ attribute :id
56
+ attribute :email
57
+ attribute :verified_email
58
+ attribute :name
59
+ attribute :given_name
60
+ attribute :family_name
61
+ attribute :link
62
+ attribute :picture
63
+ attribute :gender
64
+ attribute :locale
65
+ attribute :hd
66
+
67
+ # Set the scopes to grant access to DailyMotion user profile and email
68
+ #
69
+ # @see https://developers.google.com/+/api/oauth#profile
70
+ def self.oauth_scopes
71
+ %w(profile email)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,30 @@
1
+ module Dm
2
+ # Provides methods to read attributes for public objects (accounts, videos..)
3
+ module Readable
4
+
5
+ # Return the unique DailyMotion identifier of a DailyMotion object
6
+ def id
7
+ info[:id]
8
+ end
9
+
10
+ # Return the title of a DailyMotion object
11
+ def title
12
+ info[:snippet][:title]
13
+ end
14
+
15
+ # Return the description of a DailyMotion object
16
+ def description
17
+ info[:snippet][:description]
18
+ end
19
+
20
+ # Return the URL of the DailyMotion object thumbnail
21
+ def thumbnail_url
22
+ info[:snippet][:thumbnails][:default][:url]
23
+ end
24
+
25
+ # Return the kind of the DailyMotion object (either 'channel' or 'video')
26
+ def kind
27
+ info.fetch(:kind, '').split("#").last
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,58 @@
1
+ require 'uri'
2
+ require 'json'
3
+
4
+ module Dm
5
+ # A custom class to rescue errors from interacting with DailyMotion V3 API
6
+ class RequestError < StandardError
7
+ end
8
+
9
+ # Provides methods to send HTTP requests to DailyMotion V3 API
10
+ module Requestable
11
+ ##
12
+ # Executes an HTTP request against the DailyMotion V3 API and returns the
13
+ # parsed result or raise an error in case of failure
14
+ #
15
+ def request!(params = {})
16
+ url = URI.parse params[:host]
17
+ http = Net::HTTP.new url.host, url.port
18
+ http.use_ssl = true
19
+ request = case params[:method]
20
+ when :get then Net::HTTP::Get.new params[:path]
21
+ when :post then
22
+ if params[:json]
23
+ Net::HTTP::Post.new params[:path], initheader = {'Content-Type' =>'application/json'}
24
+ else
25
+ Net::HTTP::Post.new params[:path]
26
+ end
27
+ end
28
+ if params[:json]
29
+ request.body = params[:body].to_json
30
+ else
31
+ request.set_form_data params[:body]
32
+ end if params[:body]
33
+
34
+ request['Authorization'] = 'Bearer ' + params[:auth] if params[:auth]
35
+ response = http.request(request)
36
+
37
+ body = JSON.parse response.body if response.body
38
+
39
+ if params[:valid_if] ? params[:valid_if].call(response, body) : true
40
+ body = params[:extract].call body if params[:extract]
41
+ body ? deep_symbolize_keys(body) : true
42
+ else
43
+ raise RequestError, body
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def deep_symbolize_keys(hash)
50
+ {}.tap do |result|
51
+ hash.each do |k, v|
52
+ key = k.to_sym rescue k
53
+ result[key] = v.is_a?(Hash) ? deep_symbolize_keys(v) : v
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,11 @@
1
+ module Dm
2
+ module ServerTokens
3
+ def server_key
4
+ @@server_key
5
+ end
6
+
7
+ def self.server_key=(server_key)
8
+ @@server_key = server_key
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Dm
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,78 @@
1
+ require 'dm/authenticable'
2
+ require 'dm/readable'
3
+
4
+ module Dm
5
+ # Provides read & write access to a DailyMotion account (also known as Channel).
6
+ #
7
+ # @example Like the video "Tongue" by R.E.M. as a specific DailyMotion account:
8
+ # * Set up two pages: one with a link to authenticate, one to redirect to
9
+ # * In the first page, add a link to the authentication page:
10
+ #
11
+ # Dm::DailyMotionAccount.oauth_url(redirect_url)
12
+ #
13
+ # * The user authenticates and lands on the second page, with an extra +code+ query parameter
14
+ # * Use the authorization code to initialize the DailyMotionAccount and like the video:
15
+ #
16
+ # account = Dm::DailyMotionAccount.new code: code, redirect_url: redirect_url
17
+ # account.perform! :like, :video, 'Kd5M17e7Wek' # => likes the video
18
+ #
19
+ class DailyMotionAccount
20
+ include Authenticable
21
+ include Readable
22
+ # Return the profile info of a DailyMotion account/channel.
23
+ #
24
+ # @see https://developers.google.com/dailymotion/v3/docs/channels#resource
25
+ #
26
+ # @return [Hash]
27
+ # * :id [String] The ID that DailyMotion uses to uniquely identify the channel.
28
+ # * :etag [String] The Etag of this resource.
29
+ # * :kind [String] The value will be dailymotion#channel.
30
+ # * :snippet [Hash]
31
+ # - :title [String] The channel's title.
32
+ # - :description [String] The channel's description.
33
+ # - :publishedAt [String] The date and time that the channel was created. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.
34
+ # - :thumbnails [Hash]
35
+ # + :default [Hash] Default thumbnail URL (88px x 88px)
36
+ # + :medium [Hash] Medium thumbnail URL (88px x 88px)
37
+ # + :high [Hash] High thumbnail URL (88px x 88px)
38
+ def info
39
+ @info ||= request! method: :get,
40
+ auth: credentials[:access_token],
41
+ host: 'https://www.googleapis.com',
42
+ path: '/dailymotion/v3/channels?part=id,snippet&mine=true',
43
+ valid_if: -> resp, body {resp.code == '200' && body['items'].any?},
44
+ extract: -> body {body['items'].first}
45
+ end
46
+
47
+ ## Promote a DailyMotion target resource on this DailyMotion Channel
48
+ # Note that liking a video does not also subscribe to a channel
49
+ def perform!(activity, target_kind, target_id)
50
+ params = {}.tap do |params|
51
+ params[:method] = :post
52
+ params[:auth] = credentials[:access_token]
53
+ params[:host] = 'https://www.googleapis.com'
54
+
55
+ case [activity.to_sym, target_kind.to_sym]
56
+ when [:like, :video]
57
+ params[:path] = "/dailymotion/v3/videos/rate?rating=like&id=#{target_id}"
58
+ params[:valid_if] = -> response, body {response.code == '204'}
59
+ when [:subscribe_to, :channel]
60
+ params[:json] = true
61
+ params[:path] = '/dailymotion/v3/subscriptions?part=snippet'
62
+ params[:body] = {snippet: {resourceId: {channelId: target_id}}}
63
+ params[:valid_if] = -> response, body {response.code == '200'}
64
+ else
65
+ raise RequestError, "#{activity} invalid for #{target_kind} #{target_id}"
66
+ end
67
+ end
68
+ request! params
69
+ end
70
+
71
+ # Set the scopes to grant access to DailyMotion account
72
+ #
73
+ # @see https://developers.google.com/dailymotion/v3/guides/authentication
74
+ def self.oauth_scopes
75
+ %w(https://www.googleapis.com/auth/dailymotion)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,86 @@
1
+ require 'dm/requestable'
2
+ require 'dm/readable'
3
+ require 'dm/server_tokens'
4
+
5
+ module Dm
6
+ # Provides read-only access to a DailyMotion resource (a channel or a video).
7
+ #
8
+ # @example Get the description of the video "Tongue" by R.E.M.:
9
+ #
10
+ # resource = Dm::DailyMotionResource.new url: 'youtu.be/Kd5M17e7Wek'
11
+ # resource.description # => "© 2006 WMG\nTongue (Video)"
12
+ #
13
+ # @example Get the description of the R.E.M. channel:
14
+ #
15
+ # resource = Dm::DailyMotionResource.new url: 'dailymotion.com/remhq'
16
+ # resource.description # => "R.E.M.'s Official DailyMotion Channel"
17
+ #
18
+ # Note that this class does not require the user to authenticate.
19
+ #
20
+ class DailyMotionResource
21
+ include Requestable
22
+ include Readable
23
+ include ServerTokens
24
+ # Initialize a resource by URL
25
+ #
26
+ # @param [Hash] attrs
27
+ # @option attrs [String] :url The URL of the DailyMotion channel or video
28
+ def initialize(attrs = {})
29
+ @url = attrs[:url]
30
+ end
31
+
32
+ # Return the profile info of a DailyMotion account/channel.
33
+ #
34
+ # @see https://developers.google.com/dailymotion/v3/docs/channels#resource
35
+ #
36
+ # @return [Hash]
37
+ # * :id [String] The ID that DailyMotion uses to uniquely identify the channel.
38
+ # * :etag [String] The Etag of this resource.
39
+ # * :kind [String] The value will be dailymotion#channel.
40
+ # * :snippet [Hash]
41
+ # - :title [String] The channel's title.
42
+ # - :description [String] The channel's description.
43
+ # - :publishedAt [String] The date and time that the channel was created. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.
44
+ # - :thumbnails [Hash]
45
+ # + :default [Hash] Default thumbnail URL (88px x 88px)
46
+ # + :medium [Hash] Medium thumbnail URL (88px x 88px)
47
+ # + :high [Hash] High thumbnail URL (88px x 88px)
48
+ def info
49
+ @info ||= request! method: :get,
50
+ host: 'https://www.googleapis.com',
51
+ path: "/dailymotion/v3/#{info_path}",
52
+ valid_if: -> resp, body {resp.code == '200' && body['items'].any?},
53
+ extract: -> body {body['items'].first}
54
+ end
55
+
56
+ private
57
+
58
+ ##
59
+ # Return the path to execute the DailyMotion API request again.
60
+ # Channels and videos have different paths, so it depends on the type
61
+ #
62
+ # @return [String] Path
63
+ def info_path
64
+ @info_path ||= case @url
65
+ when regex?(:video_id) then "videos?id=#{$1}"
66
+ when regex?(:video_short_id) then "videos?id=#{$1}"
67
+ when regex?(:channel_id) then "channels?id=#{$1}"
68
+ when regex?(:channel_username) then "channels?forUsername=#{$1}"
69
+ when regex?(:channel_name) then "channels?forUsername=#{$1}"
70
+ else raise RequestError, "Invalid DailyMotion URL: #{@url}"
71
+ end + "&part=id,snippet&key=#{server_key}"
72
+ end
73
+
74
+ # Parses a URL to find the type and identifier of a DailyMotion resource
75
+ def regex?(key)
76
+ host, name = '^(?:https?://)?(?:www\.)?', '([a-zA-Z0-9_-]+)'
77
+ case key
78
+ when :video_id then %r{#{host}dailymotion\.com/watch\?v=#{name}}
79
+ when :video_short_id then %r{#{host}youtu\.be/#{name}}
80
+ when :channel_id then %r{#{host}dailymotion\.com/channel/#{name}}
81
+ when :channel_username then %r{#{host}dailymotion\.com/user/#{name}}
82
+ when :channel_name then %r{#{host}dailymotion\.com/#{name}}
83
+ end
84
+ end
85
+ end
86
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Claudio Baccigalupo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: coveralls
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: DailyMotion + DailyMotion V3 API client.
84
+ email:
85
+ - claudio@fullscreen.net
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - MIT-LICENSE
91
+ - README.md
92
+ - lib/dm.rb
93
+ - lib/dm/authenticable.rb
94
+ - lib/dm/client_tokens.rb
95
+ - lib/dm/google_account.rb
96
+ - lib/dm/readable.rb
97
+ - lib/dm/requestable.rb
98
+ - lib/dm/server_tokens.rb
99
+ - lib/dm/version.rb
100
+ - lib/dm/youtube_account.rb
101
+ - lib/dm/youtube_resource.rb
102
+ homepage: https://github.com/claudiob/dm
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 1.9.2
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: 1.3.6
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.2.2
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: Dm lets you interact with many resources provided by DailyMotion API V3.
126
+ test_files: []
127
+ has_rdoc: