multi_video_streaming 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/lib/multi_video_streaming/drivers/bunny.rb +175 -0
  3. data/lib/multi_video_streaming/drivers/s3.rb +144 -0
  4. data/lib/multi_video_streaming/drivers/vimeo.rb +174 -0
  5. data/lib/multi_video_streaming/drivers.rb +5 -0
  6. data/lib/multi_video_streaming/errors/duplicated_platform_name.rb +11 -0
  7. data/lib/multi_video_streaming/errors/invalid_platform_name.rb +11 -0
  8. data/lib/multi_video_streaming/errors/invalid_platforms_param.rb +11 -0
  9. data/lib/multi_video_streaming/errors/missing_param.rb +11 -0
  10. data/lib/multi_video_streaming/errors/s3_is_not_valid_to_upload.rb +11 -0
  11. data/lib/multi_video_streaming/errors.rb +7 -0
  12. data/lib/multi_video_streaming/factories/drive.rb +23 -0
  13. data/lib/multi_video_streaming/factories.rb +3 -0
  14. data/lib/multi_video_streaming/helpers/get_default_error_message.rb +26 -0
  15. data/lib/multi_video_streaming/helpers/title_from_url.rb +11 -0
  16. data/lib/multi_video_streaming/helpers.rb +4 -0
  17. data/lib/multi_video_streaming/platforms_support.rb +5 -0
  18. data/lib/multi_video_streaming/protocols/https.rb +15 -0
  19. data/lib/multi_video_streaming/protocols/interface.rb +13 -0
  20. data/lib/multi_video_streaming/protocols/platform.rb +32 -0
  21. data/lib/multi_video_streaming/protocols.rb +5 -0
  22. data/lib/multi_video_streaming/response.rb +124 -0
  23. data/lib/multi_video_streaming/services/https.rb +85 -0
  24. data/lib/multi_video_streaming/services.rb +3 -0
  25. data/lib/multi_video_streaming/validators/platform_name_validator.rb +13 -0
  26. data/lib/multi_video_streaming/validators/platforms_array_validator.rb +17 -0
  27. data/lib/multi_video_streaming/validators/platforms_hash_validator.rb +36 -0
  28. data/lib/multi_video_streaming/validators/platforms_position_validator.rb +17 -0
  29. data/lib/multi_video_streaming/validators/required_fields_validator.rb +15 -0
  30. data/lib/multi_video_streaming/validators.rb +7 -0
  31. data/lib/multi_video_streaming/version.rb +5 -0
  32. data/lib/multi_video_streaming.rb +104 -0
  33. metadata +130 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0c1ae1d10ba98cf2adfd9db15e18956c5ec601e0afdd47f4857c5313d5b5661c
4
+ data.tar.gz: e972c5a015cb6e813c9423d21a0993646aacc807b549797f6db638f3686823c4
5
+ SHA512:
6
+ metadata.gz: 1feb06fa08e5ec6775c208ea859371083956b99d95c71b419b040823cfa307156c1acaeb110ae012bf12c6d573636ef800752d3fb3ed3ed74415ecb6db1bac2f
7
+ data.tar.gz: a4cf1f7c854d9b3b4838e459c75417441078fccc2ac2b09ff02751855d29579126529a701efc7303da03ea5a96604da6ca8d746e2b5158b7da75a610b1c99982
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Drivers
5
+ class Bunny < MultiVideoStreaming::Protocols::Platform
6
+ PARAMS_EQUIVALENT = {
7
+ "guid" => :video_id,
8
+ "title" => :title,
9
+ "status" => :status,
10
+ "files" => :files,
11
+ "availableResolutions" => :available_resolutions,
12
+ "directPlay" => :direct_play,
13
+ "dateUploaded" => :date_uploaded
14
+ }
15
+
16
+ STATUS_EQUIVALENT = {
17
+ "0" => "processing",
18
+ "1" => "processing",
19
+ "2" => "transcoding",
20
+ "3" => "processing",
21
+ "4" => "available",
22
+ "5" => "failed"
23
+ }
24
+
25
+ BASE_URL = "https://video.bunnycdn.com"
26
+
27
+ def upload_video(url:)
28
+ begin
29
+ library_id, api_key = self.dependency_params.values_at(:library_id, :api_key)
30
+ @original_status_code = nil
31
+
32
+ self.required_fields_validator_instance.validate(library_id: library_id, api_key: api_key)
33
+
34
+ title = MultiVideoStreaming::Helpers::TitleFromUrl.get(url: url)
35
+ create_video_response = self.https_service_instance.post(uri: "#{BASE_URL}/library/#{library_id}/videos", headers: { :AccessKey => api_key }, body: { :title => title })
36
+
37
+ if create_video_response["status_code"] != 200
38
+ @original_status_code = create_video_response["status_code"]
39
+ raise create_video_response["Message"] || create_video_response["message"] || MultiVideoStreaming::Helpers::GetDefaultErrorMessage.by_method(method: :upload)
40
+ end
41
+
42
+ video_id = create_video_response["guid"]
43
+ upload_response = self.https_service_instance.post(uri: "#{BASE_URL}/library/#{library_id}/videos/#{video_id}/fetch", body: { url: url }, headers: { :AccessKey => api_key })
44
+
45
+ @original_status_code = upload_response["status_code"]
46
+
47
+ if upload_response["status_code"] != 200
48
+ self.https_service_instance.delete(uri: "#{BASE_URL}/library/#{library_id}/videos/#{video_id}", headers: { :AccessKey => api_key })
49
+ raise upload_response["Message"] || upload_response["message"] || MultiVideoStreaming::Helpers::GetDefaultErrorMessage.by_method(method: :upload)
50
+ end
51
+
52
+ create_video_response["availableResolutions"] = []
53
+ create_video_response["status"] = STATUS_EQUIVALENT[create_video_response["status"].to_s]
54
+ create_video_response["directPlay"] = "https://video.bunnycdn.com/play/#{library_id}/#{video_id}"
55
+ create_video_response["files"] = []
56
+
57
+ return self.response_instance.add_response(
58
+ platform_name: "bunny",
59
+ status: "success",
60
+ original_status_code: @original_status_code,
61
+ data: create_video_response,
62
+ params_equivalent: PARAMS_EQUIVALENT,
63
+ message: "Video uploaded successfully."
64
+ )
65
+
66
+ rescue => exception
67
+ return self.response_instance.add_response(
68
+ platform_name: "bunny",
69
+ status: "error",
70
+ original_status_code: @original_status_code,
71
+ data: {},
72
+ message: exception.message
73
+ )
74
+ end
75
+ end
76
+
77
+ def get_video
78
+ begin
79
+ video_id, library_id, pull_zone, api_key = self.dependency_params.values_at(:video_id, :library_id, :pull_zone, :api_key)
80
+ @original_status_code = nil
81
+
82
+ self.required_fields_validator_instance.validate(
83
+ library_id: library_id,
84
+ video_id: video_id,
85
+ pull_zone: pull_zone,
86
+ api_key: api_key
87
+ )
88
+
89
+ response = self.https_service_instance.get(uri: "#{BASE_URL}/library/#{library_id}/videos/#{video_id}", headers: { :AccessKey => api_key })
90
+
91
+ @original_status_code = response["status_code"]
92
+
93
+ if response["status_code"] != 200
94
+ if response["status_code"] == 404
95
+ raise MultiVideoStreaming::Helpers::GetDefaultErrorMessage.not_found(video_id: video_id)
96
+ end
97
+
98
+ raise response["Message"] || response["message"] || MultiVideoStreaming::Helpers::GetDefaultErrorMessage.by_method(method: :get)
99
+ end
100
+
101
+ response["directPlay"] = "https://video.bunnycdn.com/play/#{library_id}/#{video_id}"
102
+ response["availableResolutions"] = response["availableResolutions"].split(",")
103
+
104
+ files = []
105
+ response["availableResolutions"].map do |available_resolution|
106
+ files <<
107
+ {
108
+ file: "https://#{pull_zone}.b-cdn.net/#{response["guid"]}/play_#{available_resolution}.mp4",
109
+ label: available_resolution
110
+ }
111
+ end
112
+
113
+ response["files"] = files
114
+ status = STATUS_EQUIVALENT[response["status"].to_s]
115
+
116
+ response["status"] = STATUS_EQUIVALENT[response["status"].to_s]
117
+
118
+ return self.response_instance.add_response(
119
+ platform_name: "bunny",
120
+ status: "success",
121
+ original_status_code: @original_status_code,
122
+ data: response,
123
+ params_equivalent: PARAMS_EQUIVALENT,
124
+ message: "Video found successfully."
125
+ )
126
+ rescue => exception
127
+ return self.response_instance.add_response(
128
+ platform_name: "bunny",
129
+ status: "error",
130
+ original_status_code: @original_status_code,
131
+ data: {},
132
+ message: exception.message
133
+ )
134
+ end
135
+ end
136
+
137
+ def delete_video
138
+ begin
139
+ video_id, library_id, api_key = self.dependency_params.values_at(:video_id, :library_id, :api_key)
140
+ @original_status_code = nil
141
+
142
+ self.required_fields_validator_instance.validate(library_id: library_id, video_id: video_id, api_key: api_key)
143
+
144
+ response = self.https_service_instance.delete(uri: "#{BASE_URL}/library/#{library_id}/videos/#{video_id}", headers: { :AccessKey => api_key })
145
+
146
+ @original_status_code = response["status_code"]
147
+
148
+ if response["status_code"] != 200
149
+ if response["status_code"] == 404
150
+ raise MultiVideoStreaming::Helpers::GetDefaultErrorMessage.not_found(video_id: video_id)
151
+ end
152
+
153
+ raise response["Message"] || response["message"] || MultiVideoStreaming::Helpers::GetDefaultErrorMessage.by_method(method: :delete)
154
+ end
155
+
156
+ return self.response_instance.add_response(
157
+ platform_name: "bunny",
158
+ status: "success",
159
+ original_status_code: @original_status_code,
160
+ data: {},
161
+ message: "Video deleted successfully."
162
+ )
163
+ rescue => exception
164
+ return self.response_instance.add_response(
165
+ platform_name: "bunny",
166
+ status: "error",
167
+ original_status_code: @original_status_code,
168
+ data: {},
169
+ message: exception.message
170
+ )
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Drivers
5
+ class S3 < MultiVideoStreaming::Protocols::Platform
6
+ PARAMS_EQUIVALENT = {
7
+ "key" => :video_id,
8
+ "title" => :title,
9
+ "status" => :status,
10
+ "files" => :files,
11
+ "available_resolutions" => :available_resolutions,
12
+ "direct_play" => :direct_play,
13
+ "date_uploaded" => :date_uploaded
14
+ }
15
+
16
+ STATUS_EQUIVALENT = {
17
+ :true => "available",
18
+ :false => "failed"
19
+ }
20
+
21
+ def get_video()
22
+ begin
23
+ video_id, bucket = self.dependency_params.values_at(:video_id, :bucket)
24
+
25
+ self.required_fields_validator_instance.validate(bucket: bucket)
26
+
27
+ configure_credentials
28
+
29
+ response = Aws::S3::Resource.new().bucket(bucket).object(video_id)
30
+ video_url = response.public_url
31
+
32
+ data = {
33
+ "key": response.key,
34
+ "title": response.key,
35
+ "status": STATUS_EQUIVALENT[:true],
36
+ "files": [
37
+ {
38
+ file: video_url
39
+ }
40
+ ],
41
+ "available_resolutions": [],
42
+ "direct_play": video_url,
43
+ "date_uploaded": response.data.last_modified
44
+ }
45
+
46
+ return self.response_instance.add_response(
47
+ platform_name: "s3",
48
+ status: "success",
49
+ original_status_code: 200,
50
+ data: data,
51
+ params_equivalent: PARAMS_EQUIVALENT,
52
+ message: "Video found successfully."
53
+ )
54
+
55
+ rescue Aws::Errors::MissingCredentialsError => exception
56
+ return self.response_instance.add_response(
57
+ platform_name: "s3",
58
+ status: "error",
59
+ original_status_code: 401,
60
+ data: {},
61
+ message: exception.message
62
+ )
63
+ rescue Aws::S3::Errors::NotFound => e
64
+ return self.response_instance.add_response(
65
+ platform_name: "s3",
66
+ status: "error",
67
+ original_status_code: 404,
68
+ data: {},
69
+ message: "Video or bucket does not exist."
70
+ )
71
+ rescue => exception
72
+ return self.response_instance.add_response(
73
+ platform_name: "s3",
74
+ status: "error",
75
+ original_status_code: 500,
76
+ data: {},
77
+ message: exception.message || MultiVideoStreaming::Helpers::GetDefaultErrorMessage.by_method(method: :get)
78
+ )
79
+ end
80
+ end
81
+
82
+ def delete_video()
83
+ begin
84
+ video_id, bucket = self.dependency_params.values_at(:video_id, :bucket)
85
+ self.required_fields_validator_instance.validate(bucket: bucket)
86
+
87
+ configure_credentials
88
+
89
+ response = Aws::S3::Resource.new().bucket(bucket).object(video_id)
90
+ response.data
91
+ response.delete
92
+
93
+ return self.response_instance.add_response(
94
+ platform_name: "s3",
95
+ status: "success",
96
+ original_status_code: 200,
97
+ data: {},
98
+ message: "Video deleted successfully."
99
+ )
100
+
101
+ rescue Aws::Errors::MissingCredentialsError => exception
102
+ return self.response_instance.add_response(
103
+ platform_name: "s3",
104
+ status: "error",
105
+ original_status_code: 401,
106
+ data: {},
107
+ message: exception.message
108
+ )
109
+ rescue Aws::S3::Errors::NotFound
110
+ return self.response_instance.add_response(
111
+ platform_name: "s3",
112
+ status: "error",
113
+ original_status_code: 404,
114
+ data: {},
115
+ message: "Video or bucket does not exist."
116
+ )
117
+ rescue => exception
118
+ return self.response_instance.add_response(
119
+ platform_name: "s3",
120
+ status: "error",
121
+ original_status_code: 500,
122
+ data: {},
123
+ message: exception.message || MultiVideoStreaming::Helpers::GetDefaultErrorMessage.by_method(method: :delete)
124
+ )
125
+ end
126
+ end
127
+
128
+ private
129
+
130
+ def configure_credentials
131
+ access_key_id, secret_access_key, region, is_local = self.dependency_params.values_at(:access_key_id, :secret_access_key, :region, :is_local)
132
+ self.required_fields_validator_instance.validate(access_key_id: access_key_id, secret_access_key: secret_access_key, region: region)
133
+
134
+ credentials = Aws::Credentials.new(access_key_id, secret_access_key)
135
+
136
+ if is_local
137
+ Aws.config.update(endpoint: "http://localstack:4566", credentials: credentials, region: region, force_path_style: true)
138
+ else
139
+ Aws.config.update(credentials: credentials, region: region, force_path_style: true)
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Drivers
5
+ class Vimeo < MultiVideoStreaming::Protocols::Platform
6
+ PARAMS_EQUIVALENT = {
7
+ "vimeo_id" => :video_id,
8
+ "name" => :title,
9
+ "status" => :status,
10
+ "files" => :files,
11
+ "available_resolutions" => :available_resolutions,
12
+ "player_embed_url" => :direct_play,
13
+ "created_time" => :date_uploaded
14
+ }
15
+
16
+ STATUS_EQUIVALENT = {
17
+ "available" => "available",
18
+ "quota_exceeded" => "failed",
19
+ "total_cap_exceeded" => "failed",
20
+ "transcode_starting" => "transcoding",
21
+ "transcoding" => "transcoding",
22
+ "transcoding_error" => "failed",
23
+ "unavailable" => "failed",
24
+ "uploading" => "processing",
25
+ "uploading_error" => "failed"
26
+ }
27
+
28
+ VIMEO_URL = "https://api.vimeo.com"
29
+
30
+ def upload_video(url:)
31
+ begin
32
+ token = self.dependency_params[:token]
33
+ title = MultiVideoStreaming::Helpers::TitleFromUrl.get(url: url)
34
+ @original_status_code = nil
35
+
36
+ self.required_fields_validator_instance.validate(token: token)
37
+ response = self.https_service_instance.post(
38
+ uri: "#{VIMEO_URL}/me/videos",
39
+ headers: { :Authorization => "Bearer #{token}", :Accept => "application/vnd.vimeo.*+json;version=3.4" },
40
+ body: {
41
+ :name => title,
42
+ :upload => {
43
+ :approach => "pull",
44
+ :link => url
45
+ },
46
+ :privacy => {
47
+ :download => false,
48
+ :embed => "private",
49
+ :view => "nobody"
50
+ }
51
+ }
52
+ )
53
+
54
+ @original_status_code = response["status_code"]
55
+
56
+ if response["status_code"] != 201
57
+ raise response["developer_message"] || response["error"] || MultiVideoStreaming::Helpers::GetDefaultErrorMessage.by_method(method: :upload)
58
+ end
59
+
60
+ response["vimeo_id"] = response["uri"].split("/videos/")[1]
61
+ response["files"] = []
62
+ response["available_resolutions"] = []
63
+ response["status"] = STATUS_EQUIVALENT[response["status"]]
64
+
65
+ return self.response_instance.add_response(
66
+ platform_name: "vimeo",
67
+ status: "success",
68
+ original_status_code: @original_status_code,
69
+ data: response,
70
+ params_equivalent: PARAMS_EQUIVALENT,
71
+ message: "Video uploaded successfully."
72
+ )
73
+
74
+ rescue => exception
75
+ return self.response_instance.add_response(
76
+ platform_name: "vimeo",
77
+ status: "error",
78
+ original_status_code: @original_status_code,
79
+ data: {},
80
+ message: exception.message
81
+ )
82
+ end
83
+
84
+ end
85
+
86
+ def get_video()
87
+ begin
88
+ video_id, token = self.dependency_params.values_at(:video_id, :token)
89
+ @original_status_code = nil
90
+
91
+ self.required_fields_validator_instance.validate(token: token, video_id: video_id)
92
+
93
+ response = self.https_service_instance.get(uri: "#{VIMEO_URL}/videos/#{video_id}", headers: { :Authorization => "Bearer #{token}" })
94
+
95
+ @original_status_code = response["status_code"]
96
+ if response["status_code"] != 200
97
+ if response["status_code"] == 404
98
+ raise MultiVideoStreaming::Helpers::GetDefaultErrorMessage.not_found(video_id: video_id)
99
+ end
100
+
101
+ raise response["developer_message"] || response["error"] || MultiVideoStreaming::Helpers::GetDefaultErrorMessage.by_method(method: :get)
102
+ end
103
+
104
+ response["vimeo_id"] = response["uri"].split("/videos/")[1]
105
+
106
+ available_resolutions = []
107
+ files = []
108
+ response["files"].each do |file|
109
+ if file["rendition"] != "adaptive"
110
+ available_resolutions << file["rendition"]
111
+ files << { file: file["link"], label: file["rendition"] }
112
+ end
113
+ end
114
+
115
+ response["files"] = files
116
+ response["available_resolutions"] = available_resolutions
117
+ response["status"] = STATUS_EQUIVALENT[response["status"]]
118
+ return self.response_instance.add_response(
119
+ platform_name: "vimeo",
120
+ status: "success",
121
+ original_status_code: @original_status_code,
122
+ data: response,
123
+ params_equivalent: PARAMS_EQUIVALENT,
124
+ message: "Video found successfully."
125
+ )
126
+ rescue => exception
127
+ return self.response_instance.add_response(
128
+ platform_name: "vimeo",
129
+ status: "error",
130
+ original_status_code: @original_status_code,
131
+ data: {},
132
+ message: exception.message
133
+ )
134
+ end
135
+ end
136
+
137
+ def delete_video()
138
+ begin
139
+ video_id, token = self.dependency_params.values_at(:video_id, :token)
140
+ self.required_fields_validator_instance.validate(video_id: video_id, token: token)
141
+ @original_status_code = nil
142
+
143
+ response = self.https_service_instance.delete(uri: "#{VIMEO_URL}/videos/#{video_id}", headers: { :Authorization => "Bearer #{token}" })
144
+
145
+ @original_status_code = response["status_code"]
146
+
147
+ if response["status_code"] != 204
148
+ if response["status_code"] == 404
149
+ raise MultiVideoStreaming::Helpers::GetDefaultErrorMessage.not_found(video_id: video_id)
150
+ end
151
+
152
+ raise response["developer_message"] || response["error"] || MultiVideoStreaming::Helpers::GetDefaultErrorMessage.by_method(method: :delete)
153
+ end
154
+
155
+ return self.response_instance.add_response(
156
+ platform_name: "vimeo",
157
+ status: "success",
158
+ original_status_code: @original_status_code,
159
+ data: {},
160
+ message: "Video deleted successfully."
161
+ )
162
+ rescue => exception
163
+ return self.response_instance.add_response(
164
+ platform_name: "vimeo",
165
+ status: "error",
166
+ original_status_code: @original_status_code,
167
+ data: {},
168
+ message: exception.message
169
+ )
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "multi_video_streaming/drivers/bunny"
4
+ require "multi_video_streaming/drivers/s3"
5
+ require "multi_video_streaming/drivers/vimeo"
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Errors
5
+ class DuplicatedPlatformName < StandardError
6
+ def initialize()
7
+ super("Duplicate name platform")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Errors
5
+ class InvalidPlatformName < StandardError
6
+ def initialize(name)
7
+ super("Platform name #{name} is invalid")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Errors
5
+ class InvalidPlatformsParam < StandardError
6
+ def initialize()
7
+ super("Platforms param is invalid")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Errors
5
+ class MissingParam < StandardError
6
+ def initialize(param_name)
7
+ super("The #{param_name} dependency param is missing")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Errors
5
+ class S3IsNotValidToUpload < StandardError
6
+ def initialize()
7
+ super("S3 is not a valid platform to upload a video through MultiVideoStreaming")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "multi_video_streaming/errors/duplicated_platform_name"
4
+ require "multi_video_streaming/errors/invalid_platform_name"
5
+ require "multi_video_streaming/errors/invalid_platforms_param"
6
+ require "multi_video_streaming/errors/missing_param"
7
+ require "multi_video_streaming/errors/s3_is_not_valid_to_upload"
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Factories
5
+ class Drive
6
+ PLATFORM_DRIVERS = {}
7
+ MultiVideoStreaming::PLATFORMS_SUPPORT.each do |platform|
8
+ platform_sym = platform.capitalize().to_sym
9
+ PLATFORM_DRIVERS[platform] = MultiVideoStreaming::Drivers.const_get(platform_sym)
10
+ end
11
+
12
+ def self.get_platform_instance(platform_name:, dependency_params:, response_instance:, required_fields_validator_instance:, https_service_instance:)
13
+ PLATFORM_DRIVERS[platform_name].new(
14
+ dependency_params: dependency_params,
15
+ response_instance: response_instance,
16
+ required_fields_validator_instance: required_fields_validator_instance,
17
+ https_service_instance: https_service_instance
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "multi_video_streaming/factories/drive"
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Helpers
5
+ class GetDefaultErrorMessage
6
+ def self.by_method(method:)
7
+ methods = {
8
+ :upload => "upload",
9
+ :get => "get",
10
+ :delete => "delete"
11
+ }
12
+
13
+ current_method = methods[method]
14
+ if current_method.nil?
15
+ raise MultiVideoStreaming::Errors::MissingParam.new("method")
16
+ end
17
+
18
+ "An error occurred when trying to #{current_method} a video."
19
+ end
20
+
21
+ def self.not_found(video_id:)
22
+ "The video with id: #{video_id} does not exist."
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Helpers
5
+ class TitleFromUrl
6
+ def self.get(url:)
7
+ URI(url.to_s).path.split('/').last
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "multi_video_streaming/helpers/title_from_url.rb"
4
+ require "multi_video_streaming/helpers/get_default_error_message.rb"
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ PLATFORMS_SUPPORT = ["vimeo", "bunny", "s3"]
5
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Protocols
5
+ class Https
6
+ extend MultiVideoStreaming::Protocols::Interface
7
+
8
+ method :get
9
+ method :post
10
+ method :put
11
+ method :patch
12
+ method :delete
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Protocols
5
+ module Interface
6
+ def method(name)
7
+ define_method(name) { |*args|
8
+ raise "interface method #{name} not implemented"
9
+ }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Protocols
5
+ class Platform
6
+ extend MultiVideoStreaming::Protocols::Interface
7
+
8
+ attr_accessor :dependency_params
9
+ private :dependency_params=
10
+
11
+ attr_accessor :response_instance
12
+ private :response_instance=
13
+
14
+ attr_accessor :required_fields_validator_instance
15
+ private :required_fields_validator_instance=
16
+
17
+ attr_accessor :https_service_instance
18
+ private :https_service_instance=
19
+
20
+ def initialize(dependency_params:, response_instance:, required_fields_validator_instance:, https_service_instance:)
21
+ self.dependency_params = dependency_params
22
+ self.response_instance = response_instance
23
+ self.required_fields_validator_instance = required_fields_validator_instance
24
+ self.https_service_instance = https_service_instance
25
+ end
26
+
27
+ method :upload_video
28
+ method :get_video
29
+ method :delete_video
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "multi_video_streaming/protocols/interface"
4
+ require "multi_video_streaming/protocols/platform"
5
+ require "multi_video_streaming/protocols/https"
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ class DriverResponse
5
+ attr_accessor :platform_name
6
+ private :platform_name=
7
+
8
+ attr_accessor :status
9
+ private :status=
10
+
11
+ attr_accessor :original_status_code
12
+ private :original_status_code=
13
+
14
+ attr_accessor :data
15
+ private :data=
16
+
17
+ attr_accessor :message
18
+ private :message=
19
+
20
+ def initialize(platform_name:, status:, original_status_code:, data:, message:)
21
+ self.platform_name = platform_name
22
+ self.status = status
23
+ self.original_status_code = original_status_code
24
+ self.data = data
25
+ self.message = message
26
+ end
27
+ end
28
+
29
+ class FinalResponse
30
+ attr_accessor :response
31
+ private :response=
32
+
33
+ attr_accessor :has_error
34
+ private :has_error=
35
+
36
+ def initialize(has_error:, response:)
37
+ @has_error = has_error
38
+ @response = format_response(response: response)
39
+ end
40
+
41
+ def has_error?
42
+ @has_error
43
+ end
44
+
45
+ def response
46
+ @response
47
+ end
48
+
49
+ private
50
+ def format_response(response: )
51
+ if response.is_a?(Array)
52
+ if (response.length > 1)
53
+ return response.map { |response| DriverResponse.new(platform_name: response[:platform_name], status: response[:status], original_status_code: response[:original_status_code], data: response[:data], message: response[:message]) }
54
+ else
55
+ return DriverResponse.new(
56
+ platform_name: response[0][:platform_name],
57
+ status: response[0][:status],
58
+ original_status_code: response[0][:original_status_code],
59
+ data: response[0][:data],
60
+ message: response[0][:message]
61
+ )
62
+ end
63
+ end
64
+
65
+ DriverResponse.new(
66
+ platform_name: response[:platform_name],
67
+ status: response[:status],
68
+ original_status_code: response[:original_status_code],
69
+ data: response[:data],
70
+ message: response[:message]
71
+ )
72
+ end
73
+ end
74
+
75
+ class Response
76
+ attr_accessor :response
77
+ private :response=
78
+
79
+ attr_accessor :has_error
80
+ private :has_error=
81
+
82
+ def initialize()
83
+ @response = []
84
+ @has_error = false
85
+ end
86
+
87
+ def add_response(platform_name:, status:, original_status_code:, data:, params_equivalent: nil, message:)
88
+ if params_equivalent
89
+ response_data = format_data(data: data, params_equivalent: params_equivalent)
90
+ else
91
+ response_data = data
92
+ end
93
+
94
+ @response.push({ platform_name: platform_name, status: status, original_status_code: original_status_code, data: response_data, message: message })
95
+ if status == "error"
96
+ @has_error = true
97
+ end
98
+
99
+ status
100
+ end
101
+
102
+ def get_this_response
103
+ MultiVideoStreaming::FinalResponse.new(has_error: has_error, response: @response.last)
104
+ end
105
+
106
+ def get_all_response
107
+ MultiVideoStreaming::FinalResponse.new(has_error: has_error, response: @response)
108
+ end
109
+
110
+ private
111
+
112
+ def format_data(data:, params_equivalent:)
113
+ data_formatted = {}
114
+ data.map do |key_value|
115
+ key = key_value.first.to_s
116
+ equivalent_key = params_equivalent[key]
117
+ if equivalent_key
118
+ data_formatted[equivalent_key] = key_value.last
119
+ end
120
+ end
121
+ data_formatted
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Services
5
+ class Https < MultiVideoStreaming::Protocols::Https
6
+ def get(uri:, headers:)
7
+ config_http(uri: uri)
8
+ request = build_request(method: :get, headers: headers)
9
+ formatt_response(response: request!)
10
+ end
11
+
12
+ def post(uri:, body:, headers:)
13
+ config_http(uri: uri)
14
+ request = build_request(method: :post, headers: headers)
15
+ request.body = body.to_json
16
+ formatt_response(response: request!)
17
+ end
18
+
19
+ def put(uri:, body:, headers:)
20
+ config_http(uri: uri)
21
+ request = build_request(method: :put, headers: headers)
22
+ request.body = body
23
+ formatt_response(response: request!)
24
+ end
25
+
26
+ def patch(uri:, body:, headers:)
27
+ config_http(uri: uri)
28
+ request = build_request(method: :patch, headers: headers)
29
+ request.body = body
30
+ formatt_response(response: request!)
31
+ end
32
+
33
+ def delete(uri:, headers:)
34
+ config_http(uri: uri)
35
+ request = build_request(method: :delete, headers: headers)
36
+ formatt_response(response: request!)
37
+ end
38
+
39
+ private
40
+ def config_http(uri:)
41
+ @url = URI(uri)
42
+ @http = Net::HTTP.new(@url.host, @url.port)
43
+ @http.use_ssl = true
44
+ end
45
+
46
+ def build_request(method:, headers:)
47
+ methods = {
48
+ :post => Net::HTTP::Post.new(@url),
49
+ :get => Net::HTTP::Get.new(@url),
50
+ :put => Net::HTTP::Put.new(@url),
51
+ :patch => Net::HTTP::Patch.new(@url),
52
+ :delete => Net::HTTP::Delete.new(@url)
53
+ }
54
+
55
+ @request = methods[method]
56
+ @request["Accept"] = "application/json"
57
+ @request["Content-Type"] = "application/json"
58
+ build_headers(headers: headers)
59
+ @request
60
+ end
61
+
62
+ def build_headers(headers:)
63
+ headers_keys = headers.keys
64
+ headers_keys.each do |key|
65
+ @request[key] = headers[key]
66
+ end
67
+ @request
68
+ end
69
+
70
+ def request!
71
+ @http.request(@request)
72
+ end
73
+
74
+ def formatt_response(response:)
75
+ response_formatted = {}
76
+ if !response.body.nil? && !response.read_body&.empty?
77
+ response_formatted = JSON.parse(response.read_body)
78
+ end
79
+
80
+ response_formatted["status_code"] = response.code.to_i
81
+ response_formatted
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "multi_video_streaming/services/https"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Validators
5
+ class PlatformNameValidator
6
+ def self.validate(name:)
7
+ if !MultiVideoStreaming::PLATFORMS_SUPPORT.include?(name)
8
+ raise MultiVideoStreaming::Errors::InvalidPlatformName.new(name)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Validators
5
+ class PlatformsArrayValidator
6
+ def self.validate(platforms_array:)
7
+ if !(platforms_array.is_a?(Array))
8
+ raise MultiVideoStreaming::Errors::MissingParam.new('platforms')
9
+ end
10
+
11
+ if platforms_array.length == 0
12
+ raise MultiVideoStreaming::Errors::MissingParam.new('platforms')
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Validators
5
+ class PlatformsHashValidator
6
+ def self.validate(platforms_hash: [], method:, number_of_platforms: 0)
7
+ platform_names = []
8
+ platforms_hash.each do |platform_hash|
9
+ if (platform_hash.nil? || platform_hash[:platform_name].nil?)
10
+ raise MultiVideoStreaming::Errors::MissingParam.new('platform_name')
11
+ end
12
+
13
+ if (platform_hash[:dependency_params].nil?)
14
+ raise MultiVideoStreaming::Errors::MissingParam.new('dependency_params')
15
+ end
16
+
17
+ if method == :create && platform_hash[:platform_name] == "s3"
18
+ if number_of_platforms > 1
19
+ return
20
+ else
21
+ raise MultiVideoStreaming::Errors::S3IsNotValidToUpload.new
22
+ end
23
+ end
24
+
25
+ MultiVideoStreaming::Validators::PlatformNameValidator.validate(name: platform_hash[:platform_name])
26
+
27
+ if platform_names.include?(platform_hash[:platform_name])
28
+ raise MultiVideoStreaming::Errors::DuplicatedPlatformName.new
29
+ else
30
+ platform_names << platform_hash[:platform_name]
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Validators
5
+ class PlatformsPositionValidator
6
+ def self.validate(platforms:)
7
+ primary_platform = platforms.first
8
+ if primary_platform[:platform_name] == "s3"
9
+ platforms.delete_at(0)
10
+ platforms << primary_platform
11
+ end
12
+
13
+ platforms
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ module Validators
5
+ class RequiredFieldsValidator
6
+ def self.validate(params)
7
+ params.each do |param_name, param_value|
8
+ if param_value.nil?
9
+ raise MultiVideoStreaming::Errors::MissingParam.new(param_name)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "multi_video_streaming/validators/platforms_hash_validator"
4
+ require "multi_video_streaming/validators/required_fields_validator"
5
+ require "multi_video_streaming/validators/platforms_array_validator"
6
+ require "multi_video_streaming/validators/platform_name_validator"
7
+ require "multi_video_streaming/validators/platforms_position_validator"
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MultiVideoStreaming
4
+ VERSION = "1.0.0.beta"
5
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thread'
4
+ require 'thwait'
5
+ require "uri"
6
+ require "net/http"
7
+ require "openssl"
8
+ require "json"
9
+ require "aws-sdk-s3"
10
+
11
+ require "multi_video_streaming/platforms_support"
12
+ require "multi_video_streaming/protocols"
13
+ require "multi_video_streaming/services"
14
+ require "multi_video_streaming/drivers"
15
+ require "multi_video_streaming/factories"
16
+ require "multi_video_streaming/errors"
17
+ require "multi_video_streaming/response"
18
+ require "multi_video_streaming/helpers"
19
+ require "multi_video_streaming/version"
20
+ require "multi_video_streaming/validators"
21
+
22
+ module MultiVideoStreaming
23
+ def self.upload(url, *platforms)
24
+ threads = []
25
+
26
+ MultiVideoStreaming::Validators::PlatformsArrayValidator.validate(platforms_array: platforms)
27
+ MultiVideoStreaming::Validators::PlatformsHashValidator.validate(platforms_hash: platforms, method: :create, number_of_platforms: platforms.length)
28
+
29
+ response_instance = MultiVideoStreaming::Response.new
30
+ required_fields_validator_instance = MultiVideoStreaming::Validators::RequiredFieldsValidator
31
+ https_service_instance = MultiVideoStreaming::Services::Https.new
32
+
33
+ platforms.each do |platform|
34
+ threads << Thread.new {
35
+ platform_instance = MultiVideoStreaming::Factories::Drive.get_platform_instance(
36
+ platform_name: platform[:platform_name],
37
+ dependency_params: platform[:dependency_params],
38
+ response_instance: response_instance,
39
+ required_fields_validator_instance: required_fields_validator_instance,
40
+ https_service_instance: https_service_instance
41
+ )
42
+ platform_instance.upload_video(url: url)
43
+ }
44
+ end
45
+
46
+ ThreadsWait.all_waits(*threads)
47
+ response_instance.get_all_response
48
+ end
49
+
50
+ def self.get(*platforms)
51
+ MultiVideoStreaming::Validators::PlatformsArrayValidator.validate(platforms_array: platforms)
52
+ MultiVideoStreaming::Validators::PlatformsHashValidator.validate(platforms_hash: platforms, method: :get, number_of_platforms: platforms.length)
53
+
54
+ response_instance = MultiVideoStreaming::Response.new
55
+ required_fields_validator_instance = MultiVideoStreaming::Validators::RequiredFieldsValidator
56
+ https_service_instance = MultiVideoStreaming::Services::Https.new
57
+
58
+ platforms_in_the_correct_order = MultiVideoStreaming::Validators::PlatformsPositionValidator.validate(platforms: platforms)
59
+
60
+ platforms_in_the_correct_order.each do |platform|
61
+ platform_instance = MultiVideoStreaming::Factories::Drive.get_platform_instance(
62
+ platform_name: platform[:platform_name],
63
+ dependency_params: platform[:dependency_params],
64
+ response_instance: response_instance,
65
+ required_fields_validator_instance: required_fields_validator_instance,
66
+ https_service_instance: https_service_instance
67
+ )
68
+ platform_response = platform_instance.get_video
69
+
70
+ if platform_response == "success"
71
+ return response_instance.get_this_response
72
+ end
73
+ end
74
+
75
+ response_instance.get_all_response
76
+ end
77
+
78
+ def self.delete(*platforms)
79
+ threads = []
80
+
81
+ MultiVideoStreaming::Validators::PlatformsArrayValidator.validate(platforms_array: platforms)
82
+ MultiVideoStreaming::Validators::PlatformsHashValidator.validate(platforms_hash: platforms, method: :get, number_of_platforms: platforms.length)
83
+
84
+ response_instance = MultiVideoStreaming::Response.new
85
+ required_fields_validator_instance = MultiVideoStreaming::Validators::RequiredFieldsValidator
86
+ https_service_instance = MultiVideoStreaming::Services::Https.new
87
+
88
+ platforms.each do |platform|
89
+ threads << Thread.new {
90
+ platform_instance = MultiVideoStreaming::Factories::Drive.get_platform_instance(
91
+ platform_name: platform[:platform_name],
92
+ dependency_params: platform[:dependency_params],
93
+ response_instance: response_instance,
94
+ required_fields_validator_instance: required_fields_validator_instance,
95
+ https_service_instance: https_service_instance
96
+ )
97
+ platform_instance.delete_video
98
+ }
99
+ end
100
+
101
+ ThreadsWait.all_waits(*threads)
102
+ response_instance.get_all_response
103
+ end
104
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: multi_video_streaming
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.beta
5
+ platform: ruby
6
+ authors:
7
+ - Henrique Schmeller
8
+ - Gustavo Voigt
9
+ - Matheus Mazepa
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2022-08-10 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '3.0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: faker
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '2.12'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '2.12'
43
+ - !ruby/object:Gem::Dependency
44
+ name: simplecov
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.17'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '0.17'
57
+ - !ruby/object:Gem::Dependency
58
+ name: aws-sdk-s3
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - '='
62
+ - !ruby/object:Gem::Version
63
+ version: 1.96.2
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '='
69
+ - !ruby/object:Gem::Version
70
+ version: 1.96.2
71
+ description: A ruby gem for multiples streaming video services
72
+ email:
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - lib/multi_video_streaming.rb
78
+ - lib/multi_video_streaming/drivers.rb
79
+ - lib/multi_video_streaming/drivers/bunny.rb
80
+ - lib/multi_video_streaming/drivers/s3.rb
81
+ - lib/multi_video_streaming/drivers/vimeo.rb
82
+ - lib/multi_video_streaming/errors.rb
83
+ - lib/multi_video_streaming/errors/duplicated_platform_name.rb
84
+ - lib/multi_video_streaming/errors/invalid_platform_name.rb
85
+ - lib/multi_video_streaming/errors/invalid_platforms_param.rb
86
+ - lib/multi_video_streaming/errors/missing_param.rb
87
+ - lib/multi_video_streaming/errors/s3_is_not_valid_to_upload.rb
88
+ - lib/multi_video_streaming/factories.rb
89
+ - lib/multi_video_streaming/factories/drive.rb
90
+ - lib/multi_video_streaming/helpers.rb
91
+ - lib/multi_video_streaming/helpers/get_default_error_message.rb
92
+ - lib/multi_video_streaming/helpers/title_from_url.rb
93
+ - lib/multi_video_streaming/platforms_support.rb
94
+ - lib/multi_video_streaming/protocols.rb
95
+ - lib/multi_video_streaming/protocols/https.rb
96
+ - lib/multi_video_streaming/protocols/interface.rb
97
+ - lib/multi_video_streaming/protocols/platform.rb
98
+ - lib/multi_video_streaming/response.rb
99
+ - lib/multi_video_streaming/services.rb
100
+ - lib/multi_video_streaming/services/https.rb
101
+ - lib/multi_video_streaming/validators.rb
102
+ - lib/multi_video_streaming/validators/platform_name_validator.rb
103
+ - lib/multi_video_streaming/validators/platforms_array_validator.rb
104
+ - lib/multi_video_streaming/validators/platforms_hash_validator.rb
105
+ - lib/multi_video_streaming/validators/platforms_position_validator.rb
106
+ - lib/multi_video_streaming/validators/required_fields_validator.rb
107
+ - lib/multi_video_streaming/version.rb
108
+ homepage: https://rubygems.org/gems/multi_video_streaming
109
+ licenses: []
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">"
123
+ - !ruby/object:Gem::Version
124
+ version: 1.3.1
125
+ requirements: []
126
+ rubygems_version: 3.0.3
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: multi_video_streaming
130
+ test_files: []