dm_cloud 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # DmCloud
1
+ # DMCloud
2
2
 
3
3
  I created this gem to simplify request and responses from DailyMotion Cloud API.
4
4
  With this gem, you can :
@@ -23,9 +23,9 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
- First, your will need to specify your :user_id, :api_key and your security level.
27
- I used a file in `APP_ROOT/config/initializers/conf.rb`.
28
- You can note the securitylevel, for more information about it, take a look at ``
26
+ First, your will need to specify your :user_id, :api_key and your security level.
27
+ I used a file in `APP_ROOT/config/initializers/conf.rb`.
28
+ You can note the securitylevel, for more information about it, take a look at `lib/dm_cloud/signing.rb`.
29
29
 
30
30
  # DAILYMOTION CLOUD SETTINGS
31
31
  require 'dm_cloud'
@@ -39,23 +39,60 @@ You can note the securitylevel, for more information about it, take a look at ``
39
39
  :security_level => DMC_SECURITY_LEVEL
40
40
  })
41
41
 
42
-
43
-
44
- Second part, how to get you embed url :
42
+ Description of security levels :
43
+
44
+ * **None:**
45
+ The signed URL will be valid for everyone
46
+ * **ASNUM:**
47
+ The signed URL will only be valid for the AS of the end-user.
48
+ The ASNUM (for Autonomous System Number) stands for the network identification,
49
+ each ISP have a different ASNUM for instance.
50
+ * **IP:**
51
+ The signed URL will only be valid for the IP of the end-user.
52
+ This security level may wrongly block some users
53
+ which have their internet access load-balanced between several proxies.
54
+ This is the case in some office network or some ISPs.
55
+ * **User-Agent:**
56
+ Used in addition to one of the two former levels,
57
+ this level a limit on the exact user-agent of the end-user.
58
+ This is more secure but in some specific condition may lead to wrongly blocked users.
59
+ * **Use Once:**
60
+ The signed URL will only be usable once.
61
+ Note: should not be used with stream URLs.
62
+ * **Country:**
63
+ The URL can only be queried from specified countrie(s).
64
+ The rule can be reversed to allow all countries except some.
65
+ * **Referer:**
66
+ The URL can only be queried
67
+ if the Referer HTTP header contains a specified value.
68
+ If the URL contains a Referer header with a different value,
69
+ the request is refused. If the Referer header is missing,
70
+ the request is accepted in order to prevent from false positives as some browsers,
71
+ anti-virus or enterprise proxies may remove this header.
72
+ * **Delegate:**
73
+ This option instructs the signing algorithm
74
+ that security level information won’t be embeded into the signature
75
+ but gathered and lock at the first use.
76
+
77
+
78
+ Second part, get you embed url :
79
+ It will return a string containing the iframe with the DailyMotion Cloud player.
45
80
 
46
81
  DMCloud::Streaming.embed('your video id looks like a secret key')
47
82
 
48
- Or how to get your direct url :
83
+ Or how to get your direct url :
84
+ It will return a string containing the direct link to your file.
49
85
 
50
86
  DMCloud::Streaming.url('your video id', ['asset_name'], {options})
51
87
 
52
- The next parts will come soon, just need some time to finish its and create corresponding tests.
88
+ The next parts will come soon, just need some time to finish it
89
+ and create corresponding tests.
53
90
 
54
91
  ## Contributing
55
92
 
56
- Your welcome to share and enhance this gem.
57
- This is my first one (and not the last one) but I know some mistakes might be done by myself.
58
- I do my best and I'm open to all ideas or comments about my work.
93
+ Your welcome to share and enhance this gem.
94
+ This is my first one (and not the last one) but I know some mistakes might be done by myself.
95
+ I do my best and I'm open to all ideas or comments about my work.
59
96
 
60
97
  1. Fork it
61
98
  2. Create your feature branch (`git checkout -b my-new-feature`)
@@ -0,0 +1,132 @@
1
+ module DMCloud
2
+ module Builder
3
+ module Media
4
+ def self.create(url = '', assets_names = [], meta = {})
5
+ request = Hash.new
6
+
7
+ request['url'] = url
8
+
9
+ if not meta.empty?
10
+ request['meta'] = {}
11
+ request['meta']['author'] = meta[:author] if meta[:author]
12
+ request['meta']['author'] = meta[:title] if meta[:title]
13
+ end
14
+
15
+ request['assets_names'] = assets_names if not assets_names.empty?
16
+
17
+ request.rehash
18
+ end
19
+
20
+ def self.info(media_id, assets_names = ['source'], fields = {})
21
+ raise StandardError, "missing :media_id in params" unless media_id
22
+ request = Hash.new
23
+
24
+ puts 'media_id :' + media_id
25
+
26
+ # the media id
27
+ request['id'] = media_id
28
+ request['fields'] = []
29
+
30
+
31
+ # requested media meta datas
32
+ fields[:meta].each { |value| request['fields'] << "meta.#{value}" } if fields[:meta].present?
33
+
34
+ #the creation date as a unix timestamp
35
+ request['fields'] << 'created' if fields[:created]
36
+
37
+ # the url of the embed player
38
+ request['fields'] << 'embed_url' if fields[:embed_url]
39
+
40
+ # the ratio of the video frame as a float (eg: 16/9, 4/3, etc).
41
+ request['fields'] << 'frame_ratio' if fields[:frame_ratio]
42
+ # the worldwide statistics on the number of views
43
+ # request['fields'] << 'stats.global.last_week' if fields[:stats][:global]
44
+
45
+ # TODO: handle statistics request per country
46
+ # fields[:stats].each { |key| request << "meta.#{key.to_s}" } if fields[:meta].present?
47
+ # request['stats'][COUNTRY_CODE][TIME_INTERVAL] : the statistics on the number of views in a specific country (eg: stats.fr.total, stats.us.last_week, etc...)
48
+ # request['extended_stats'][COUNTRY_CODE][TIME_INTERVAL]
49
+
50
+ assets_names = ['source'] if assets_names.nil?
51
+ if not fields[:assets]
52
+ request = all_assets_fields(request, assets_names)
53
+ else
54
+ assets_names.each do |name|
55
+ fields[:assets].each { |value| request << "assets.#{name}.#{value.to_s}" }
56
+ end
57
+ end
58
+
59
+ request
60
+ end
61
+
62
+ def self.list(fields = {})
63
+ # raise StandardError, "missing :media_id in params" unless media_id
64
+ request = Hash.new
65
+
66
+ request['fields'] = []
67
+ # requested media meta datas
68
+ fields[:meta].each { |key| request << "meta.#{key.to_s}" } if fields[:meta].present?
69
+
70
+ #the creation date as a unix timestamp
71
+ request['fields'] << 'created' if fields[:created]
72
+
73
+ # the url of the embed player
74
+ request['fields'] << 'embed_url' if fields[:embed_url]
75
+
76
+ # the ratio of the video frame as a float (eg: 16/9, 4/3, etc).
77
+ request['fields'] << 'frame_ratio' if fields[:frame_ratio]
78
+
79
+ # TODO: handle global statistics request in another module
80
+ # the worldwide statistics on the number of views
81
+ # request << 'stats.global.last_week' if fields[:stats][:global]
82
+
83
+ # TODO: handle statistics request per country
84
+ # fields[:stats].each { |key| request << "meta.#{key.to_s}" } if fields[:meta].present?
85
+ # request['stats'][COUNTRY_CODE][TIME_INTERVAL] : the statistics on the number of views in a specific country (eg: stats.fr.total, stats.us.last_week, etc...)
86
+ # request['extended_stats'][COUNTRY_CODE][TIME_INTERVAL]
87
+
88
+ assets_names = ['source'] if assets_names.nil?
89
+ if not fields[:assets]
90
+ request = all_assets_fields(request, assets_names)
91
+ else
92
+ assets_names.each do |name|
93
+ fields[:assets].each { |value| request << "assets.#{name}.#{value.to_s}" }
94
+ end
95
+ end
96
+
97
+ request
98
+ end
99
+
100
+
101
+ protected
102
+ # This method exclude stats, but return all information for a media (video or images)
103
+ def self.all_assets_fields(request, assets_names)
104
+ assets_names.each do |name|
105
+ request['fields'] << "assets.#{name}.download_url"
106
+ request['fields'] << "assets.#{name}.status"
107
+ request['fields'] << "assets.#{name}.container"
108
+ request['fields'] << "assets.#{name}.duration"
109
+ request['fields'] << "assets.#{name}.global_bitrate"
110
+ request['fields'] << "assets.#{name}.video_codec"
111
+ request['fields'] << "assets.#{name}.video_width"
112
+ request['fields'] << "assets.#{name}.video_height"
113
+ request['fields'] << "assets.#{name}.video_bitrate"
114
+ request['fields'] << "assets.#{name}.video_rotation"
115
+ request['fields'] << "assets.#{name}.video_fps"
116
+ request['fields'] << "assets.#{name}.video_fps_mode"
117
+ request['fields'] << "assets.#{name}.video_aspect"
118
+ request['fields'] << "assets.#{name}.video_interlaced"
119
+ request['fields'] << "assets.#{name}.audio_codec"
120
+ request['fields'] << "assets.#{name}.audio_bitrate"
121
+ request['fields'] << "assets.#{name}.audio_nbr_channel"
122
+ request['fields'] << "assets.#{name}.audio_samplerate"
123
+ request['fields'] << "assets.#{name}.created"
124
+ request['fields'] << "assets.#{name}.file_extension"
125
+ request['fields'] << "assets.#{name}.file_size"
126
+ end
127
+ request
128
+ end
129
+
130
+ end
131
+ end
132
+ end
@@ -1,3 +1,5 @@
1
+ require 'dm_cloud/builder/media'
2
+
1
3
  module DMCloud
2
4
  class Media
3
5
  # Creates a new media object.
@@ -13,14 +15,14 @@ module DMCloud
13
15
  # when you set this parameter you must also set the url parameter
14
16
  # Return :
15
17
  # media_id: return the media id of the object
16
- def self.create(media_id)
17
- call = "media.create"
18
+ def self.create(options)
19
+ call_type = "media.create"
18
20
 
19
21
  params = {
20
- call: call,
21
- args: DMCloud::Builder::Media.create(args)
22
+ :call => call_type,
23
+ args: Builder::Media.create(options)
22
24
  }
23
- DMCloud::Request.execute(call, params)
25
+ DMCloud::Request.execute(call_type, params)
24
26
  end
25
27
 
26
28
  # Delete a media object with all its associated assets.
@@ -29,43 +31,55 @@ module DMCloud
29
31
  # id (media ID) – (required) the id of the media object you want to delete.
30
32
  # Return :
31
33
  # Nothing
32
- def self.delete
33
- call = "media.delete"
34
+ def self.delete(media_id)
35
+ call_type = "media.delete"
34
36
 
35
37
  params = {
36
- call: call,
38
+ :call => call_type,
37
39
  args: { id: media_id}
38
40
  }
39
- DMCloud::Request.execute(call, params)
41
+ DMCloud::Request.execute(call_type, params)
40
42
  end
41
43
 
42
- def self.info(fields = [])
43
- call = "media.info"
44
+ # Gives information about a given media object.
45
+ #
46
+ # Params :
47
+ # media_id: (media ID) – (required) the id of the new media object.
48
+ # fields (Array) – (required) the list of fields to retrieve.
49
+ # Returns:
50
+ # a multi-level structure containing about the media related to the requested fields.
51
+ def self.info(media_id, assets_names = ['source'], fields = [])
52
+ call_type = "media.info"
44
53
 
45
54
  params = {
46
- call: call,
47
- args: DMCloud::Builder::Media.info(fields)
55
+ :call => call_type,
56
+ args: DMCloud::Builder::Media.info(media_id, assets_names, fields)
48
57
  }
49
- DMCloud::Request.execute(call, params)
58
+ DMCloud::Request.execute(call_type, params)
50
59
  end
51
60
 
52
- # Gives information about a given media object.
61
+ # Returns a paginated list of media info structures.
62
+ # You must specify the fields you want to retrieve.
63
+ # The fields are described in the documentation of the method info.
53
64
  #
54
- # Params :
55
- # media_id: (media ID) – (required) the id of the new media object.
56
- # fields (Array) – (required) the list of fields to retrieve.
57
- # Returns: a multi-level structure containing about the media related to the requested fields.
58
- Return type: Object
65
+ # Parameters:
66
+ # options:
67
+ # fields (Array) – (optional default return all informations) the fields to retrieve
68
+ # page (Integer) (optional) the page number, default: 1
69
+ # per_page (Integer) – (optional) the number of objet per page, default: 10
70
+ # Returns:
71
+ # an object with information for the pagination and the result of the query.
59
72
  def self.list(options = {})
60
- call = "media.list"
73
+ call_type = "media.list"
74
+
61
75
  page = options[:page].present? ? options[:page] : 1
62
76
  per_page = options[:per_page].present? ? options[:per_page] : 10
63
77
 
64
78
  params = {
65
- call: call,
79
+ :call => call_type,
66
80
  args: DMCloud::Builder::Media.list(options)
67
81
  }
68
- DMCloud::Request.execute(call, params)
82
+ DMCloud::Request.execute(call_type, params)
69
83
  end
70
84
 
71
85
  end
@@ -1,13 +1,38 @@
1
+ require 'net/http'
2
+
1
3
  module DMCloud
2
4
  class Request
3
5
 
6
+ DAILYMOTION_API = 'http://api.dmcloud.net/api'
7
+
8
+ def self.send_request(params)
9
+ puts 'params : ' + params.to_yaml
10
+ @uri = URI.parse(DAILYMOTION_API)
11
+
12
+ http = Net::HTTP.new(@uri.host, @uri.port)
13
+ request = Net::HTTP::Post.new(@uri.request_uri)
14
+ # request.basic_auth @uri.user, @uri.password
15
+ request.content_type = 'application/json'
16
+ request.body = params.to_json
17
+
18
+ puts 'request : ' + request.to_yaml
19
+
20
+ http.request(request).body
21
+
22
+ end
23
+
4
24
 
5
25
  def self.execute(call, params = {})
6
- request = DMCloud.identify(params)
26
+ request = DMCloud::Signing.identify(params)
7
27
  params.merge!({'auth' => request})
8
- result = DMCloud::Request.new(params)
9
- DMCloud::Response.parse(call, result)
28
+ result = send_request(params)
29
+ parse_response(result)
10
30
  end
11
31
 
32
+ def self.parse_response(result)
33
+ puts 'result : ' + result.to_yaml
34
+ end
35
+
36
+
12
37
  end
13
38
  end
@@ -1,5 +1,24 @@
1
1
  module DMCloud
2
2
  class Signing
3
+ # Generate auth token for request from Media
4
+ # Params:
5
+ # request: A hash of params generated from Media methods and Media::MetaData
6
+ # Result :
7
+ # return a string which contain the auth token for the request
8
+ # <url>?auth=<expires>-<sec>-<nonce>-<md5sum>[-<pub-sec-data>]
9
+ def self.identify(request)
10
+ user_id = DMCloud.config[:user_key]
11
+ api_key = DMCloud.config[:secret_key]
12
+
13
+ normalized_request = normalize(request).to_s
14
+ params = user_id + normalized_request + api_key
15
+
16
+ checksum = Digest::MD5.hexdigest(params)
17
+ auth_token = user_id + ':' + checksum
18
+
19
+ auth_token
20
+ end
21
+
3
22
  # To sign a URL, the client needs a secret shared with Dailymotion Cloud.
4
23
  # This secret is call client secret and is available in the back-office interface.
5
24
  # Params:
@@ -142,5 +161,11 @@ module DMCloud
142
161
  end
143
162
  result
144
163
  end
164
+
165
+ def self.normalize(params)
166
+ str = params.to_json.to_s
167
+ str.gsub!(/[^A-Za-z0-9]/, '')
168
+ str
169
+ end
145
170
  end
146
171
  end
@@ -1,3 +1,3 @@
1
1
  module DMCloud
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/dm_cloud.rb CHANGED
@@ -36,14 +36,6 @@ module DMCloud
36
36
  @@config
37
37
  end
38
38
 
39
- def self.identify(request)
40
- user_id = @@config[:user_id]
41
- api_key = @@config[:api_key]
42
- checksum = md5(user_id + normalize(request) + api_key)
43
-
44
- auth_token = user_id + ':' + checksum
45
- end
46
-
47
39
  def self.create_has_library(library)
48
40
  define_singleton_method("has_#{library}?") do
49
41
  cv="@@#{library}"
@@ -58,9 +50,9 @@ module DMCloud
58
50
  class_variable_get(cv)
59
51
  end
60
52
  end
61
-
62
- create_has_library :treaming
63
53
 
54
+ create_has_library :streaming
55
+ create_has_library :media
64
56
 
65
57
  class << self
66
58
  # Load a object saved on a file.
@@ -76,8 +68,9 @@ module DMCloud
76
68
  end
77
69
 
78
70
  autoload(:Streaming, 'dm_cloud/streaming')
79
-
80
-
71
+ autoload(:Media, 'dm_cloud/media')
72
+ autoload(:Request, 'dm_cloud/request')
73
+ autoload(:Signing, 'dm_cloud/signing')
81
74
  end
82
75
 
83
- Dir.glob('dm_cloud/**/*.rb').each{ |m| require File.dirname(__FILE__) + '/dm_cloud/' + m }
76
+ # Dir.glob('dm_cloud/**/*.rb').each{ |m| require File.dirname(__FILE__) + '/dm_cloud/' + m }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -26,6 +26,7 @@ files:
26
26
  - Rakefile
27
27
  - dm_cloud.gemspec
28
28
  - lib/dm_cloud.rb
29
+ - lib/dm_cloud/builder/media.rb
29
30
  - lib/dm_cloud/media.rb
30
31
  - lib/dm_cloud/request.rb
31
32
  - lib/dm_cloud/signing.rb