multi_video_streaming 1.0.0.beta

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.
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: []