eivid 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +215 -0
- data/Rakefile +18 -0
- data/app/controllers/eivid/application_controller.rb +20 -0
- data/app/controllers/eivid/concerns/video_validations.rb +42 -0
- data/app/controllers/eivid/videos_controller.rb +48 -0
- data/app/dump/eivid/video_mime_dump.rb +9 -0
- data/app/errors/eivid/incorrect_video_mime_type_error.rb +4 -0
- data/app/errors/eivid/main_app_record_not_found_error.rb +4 -0
- data/app/errors/eivid/maximum_vimeo_poll_reached_error.rb +4 -0
- data/app/errors/eivid/video_file_not_present_error.rb +4 -0
- data/app/errors/eivid/video_file_size_too_big_error.rb +4 -0
- data/app/errors/eivid/video_unavailable_error.rb +4 -0
- data/app/errors/eivid/video_urls_unavailable_error.rb +4 -0
- data/app/jobs/eivid/application_job.rb +4 -0
- data/app/jobs/eivid/check_vimeo_status_job.rb +46 -0
- data/app/jobs/eivid/get_vimeo_urls_job.rb +62 -0
- data/app/jobs/eivid/upload_vimeo_job.rb +55 -0
- data/app/mailers/eivid/application_mailer.rb +6 -0
- data/app/models/eivid/application_record.rb +5 -0
- data/app/models/eivid/concerns/main_app/owner.rb +17 -0
- data/app/models/eivid/concerns/main_app/user.rb +11 -0
- data/app/models/eivid/concerns/main_app/video_concerns.rb +16 -0
- data/app/models/eivid/concerns/main_app/video_resource.rb +11 -0
- data/app/models/eivid/concerns/request_service/delete_video.rb +17 -0
- data/app/models/eivid/concerns/request_service/get_video.rb +9 -0
- data/app/models/eivid/concerns/request_service/manage_folder.rb +29 -0
- data/app/models/eivid/concerns/request_service/poll_status.rb +9 -0
- data/app/models/eivid/concerns/request_service/testing_methods.rb +38 -0
- data/app/models/eivid/concerns/request_service/upload_video.rb +31 -0
- data/app/models/eivid/owner.rb +21 -0
- data/app/models/eivid/video.rb +21 -0
- data/app/models/eivid/video_resource.rb +8 -0
- data/app/services/eivid/notify_front_service.rb +14 -0
- data/app/services/eivid/request_service.rb +42 -0
- data/app/services/eivid/upload_service.rb +30 -0
- data/config/initializers/macro_initializer.rb +22 -0
- data/config/routes.rb +8 -0
- data/db/migrate/20210325114212_create_eivid_videos.rb +11 -0
- data/db/migrate/20210325140804_add_uploaded_bool_to_videos.rb +5 -0
- data/db/migrate/20210330092643_create_eivid_owners.rb +9 -0
- data/db/migrate/20210330094604_add_external_id_to_owner.rb +5 -0
- data/db/migrate/20210330100147_add_folder_id_to_owner.rb +5 -0
- data/db/migrate/20210330103729_add_vimeo_id_to_videos.rb +5 -0
- data/db/migrate/20210331082454_add_status_poll_cnt_to_videos.rb +5 -0
- data/db/migrate/20210401091448_create_eivid_video_resources.rb +12 -0
- data/db/migrate/20210401123512_remove_status_poll_cnt_from_eivid_videos.rb +5 -0
- data/db/migrate/20210401132759_create_eivid_dev_envs.rb +11 -0
- data/db/migrate/20210401134700_drop.rb +5 -0
- data/db/migrate/20210419122001_change_url_to_embedded_url.rb +5 -0
- data/db/migrate/20210419122752_add_video_urls_to_videos.rb +7 -0
- data/db/migrate/20210420120017_add_user_id_to_eivid_videos.rb +5 -0
- data/lib/eivid.rb +6 -0
- data/lib/eivid/engine.rb +33 -0
- data/lib/eivid/version.rb +3 -0
- data/lib/tasks/eivid_tasks.rake +4 -0
- metadata +144 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 98674e7ecdf813a76dda68ec8f37ad5a1ba3bee64c3c480d50b8f4d5f2cee8b1
|
4
|
+
data.tar.gz: 3371b018b813ad3abde17f2ec6e5843d71227c98b1eff1fc8606bdd77863979e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c631a4883bd2318cd4ee1da40344e45e9b30158225f69187ca5bb14c3389d2fca39f1481ed0911ed35acc9a3892ec9058ae33b88a27213fbe6c41e9f43fca1f8
|
7
|
+
data.tar.gz: f2f2d8e6ffcdec2242614f2cf86ac9f1ef45738d525912f919757b3a9d99b222c6c8a26e7c2a5d25404b13e04be8dd17ad7704bf49f45c6e2620f3681a85d03b
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2021 Jurriaan Schrofer
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
# Eivid
|
2
|
+
|
3
|
+
Never stops streaming awesome videos, yay!
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add the following to your application's Gemfile and run $bundle:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
|
13
|
+
gem 'eivid', git: 'https://github.com/eitje-app/eivid_engine', branch: 'production'
|
14
|
+
|
15
|
+
```
|
16
|
+
Or, for development purposes, add instead:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
local_eivid_path = "/Users/jurriaanschrofer/Documents/eivid"
|
20
|
+
if ENV["RAILS_ENV"] == 'development' && Dir.glob(local_eivid_path).any?
|
21
|
+
gem 'eivid', path: local_eivid_path
|
22
|
+
else
|
23
|
+
gem 'eivid', git: 'https://github.com/eitje-app/eivid_engine', branch: 'production'
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
Add the following file to your app's config/initializers directory:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
|
31
|
+
# eivid.rb
|
32
|
+
|
33
|
+
Eivid.set_mattr_accessors do |config|
|
34
|
+
config.owner_model = "owner"
|
35
|
+
end
|
36
|
+
|
37
|
+
```
|
38
|
+
|
39
|
+
In this file, set the {owner_model} to your apps owner of videos, which generates the following methods (in this example config.owner_model is set to "organisation"):
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
|
43
|
+
# retrieves the owner_id from a record
|
44
|
+
Eivid::Video.first.organisation_id
|
45
|
+
|
46
|
+
# returns the owner record of your application
|
47
|
+
Eivid::Video.first.organisation
|
48
|
+
|
49
|
+
# scope, which returns all records for your application's organisation
|
50
|
+
Eivid::Video.of_organisation(id)
|
51
|
+
|
52
|
+
# returns the owner record of your application
|
53
|
+
Eivid::Owner.organisation
|
54
|
+
|
55
|
+
```
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
## Setup
|
60
|
+
|
61
|
+
Create and run the required migrations:
|
62
|
+
|
63
|
+
```bash
|
64
|
+
|
65
|
+
$ rails eivid:install:migrations
|
66
|
+
$ rails db:migrate
|
67
|
+
|
68
|
+
```
|
69
|
+
|
70
|
+
For your application's owner model (in this example Organisation), run the following command, which creates all dedicated folders within Vimeo:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
|
74
|
+
Organisation.find_each { |owner| Eivid::Owner.create(external_id: owner.id) }
|
75
|
+
|
76
|
+
```
|
77
|
+
|
78
|
+
Add the following to your routes.rb:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
|
82
|
+
mount Eivid::Engine => "/eivid"
|
83
|
+
|
84
|
+
```
|
85
|
+
|
86
|
+
Set the following environment variables in your application:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
|
90
|
+
VIMEO_ACCESS_TOKEN
|
91
|
+
|
92
|
+
```
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
## Include Owner
|
97
|
+
|
98
|
+
Witin your application's owner model (in this example Organisation), add to following:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
|
102
|
+
eivid_owner
|
103
|
+
|
104
|
+
```
|
105
|
+
|
106
|
+
Which runs an after_create effect, which creates an Eivid::Owner for every new Organisation record, and generates the following methods within your application:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
|
110
|
+
# returns a single Eivid::Owner record for the owner, which includes a Vimeo folder_id
|
111
|
+
Organisation.first.video_owner
|
112
|
+
|
113
|
+
#returns all Eivid::Video records, which each contain an url to the video and vimeo_id
|
114
|
+
Organisation.first.videos
|
115
|
+
|
116
|
+
```
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
## Include VideoResource
|
121
|
+
|
122
|
+
Besides an owner, an Eivid::Video can belongs to many resources of your main application, e.g. a Post, Manual or Message. This functionality is provided through a join table Eivid::VideoResource, which enables any model of your application to has_many Eivid::VideoResource. In order to create this association, paste the following code in your application's resource holder:
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
|
126
|
+
eivid_video_resource
|
127
|
+
|
128
|
+
```
|
129
|
+
|
130
|
+
Which generates the following methods within your application (in this example for a Post model):
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
|
134
|
+
# returns join table records
|
135
|
+
Post.first.video_resources
|
136
|
+
|
137
|
+
# returns video records
|
138
|
+
Post.first.videos
|
139
|
+
|
140
|
+
# scope which returns all records (here Post instances) which have a video
|
141
|
+
Post.has_video
|
142
|
+
|
143
|
+
# scope which returns all records (here Post instances) which do not have a video
|
144
|
+
Post.has_not_video
|
145
|
+
|
146
|
+
```
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
## Include User
|
151
|
+
|
152
|
+
An Eivid::Video can optionally belong to your application's User model. If you want to hook up your User with Eivid::Video, include the following in your user.rb file.
|
153
|
+
|
154
|
+
Note: for the user_id to be added to a Eivid::Video record, your main application should provide an User instance @user within your controllers.
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
|
158
|
+
eivid_user
|
159
|
+
|
160
|
+
```
|
161
|
+
|
162
|
+
Which generates the following methods within your application:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
|
166
|
+
# returns video records
|
167
|
+
User.first.videos
|
168
|
+
|
169
|
+
# returns join table records
|
170
|
+
User.first.video_resources
|
171
|
+
|
172
|
+
# returns an User instance
|
173
|
+
Eivid::Video.first.user
|
174
|
+
|
175
|
+
```
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
## Optional Config: Set Controller before_action
|
182
|
+
|
183
|
+
Before each controller action, the the @owner variable is set through through ```params['external_owner_id']```. If you want to overwrite this logic, because your main application already has some kind of standardized before hooks, you can do that by setting the following in your config/initializers/eivid.rb file. This code will be evaluated, instead of ```params['external_owner_id']```.
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
|
187
|
+
Eivid.set_mattr_accessors do |config|
|
188
|
+
config.infer_external_owner_id = "@env.organisation.id"
|
189
|
+
end
|
190
|
+
|
191
|
+
```
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
## Optional Config: Set Front End Notifications
|
196
|
+
|
197
|
+
If you want your front end to be notified on the progress of the videos being uploaded to vimeo, you can add the following to your eivid.rb config file. The method fields should be any proc and accept a single positional hash as argument, which stores all the progress information. This proc will be called on any progress change, thus enabbles you to set which method in your main application should handle the change.
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
|
201
|
+
# eivid.rb
|
202
|
+
|
203
|
+
Eivid.set_mattr_accessors do |config|
|
204
|
+
config.notify_front_enabled = true
|
205
|
+
config.notify_method_on_upload = -> (data) { "NotifyFrontOnVimeoService.progress(#{data})" }
|
206
|
+
config.notify_method_on_video_available = -> (data) { "NotifyFrontOnVimeoService.progress(#{data})" }
|
207
|
+
config.notify_method_on_versions_available = -> (data) { "NotifyFrontOnVimeoService.progress(#{data})" }
|
208
|
+
end
|
209
|
+
|
210
|
+
```
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
|
3
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
4
|
+
load "rails/tasks/engine.rake"
|
5
|
+
|
6
|
+
load "rails/tasks/statistics.rake"
|
7
|
+
|
8
|
+
require "bundler/gem_tasks"
|
9
|
+
|
10
|
+
require "rake/testtask"
|
11
|
+
|
12
|
+
Rake::TestTask.new(:test) do |t|
|
13
|
+
t.libs << 'test'
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
15
|
+
t.verbose = false
|
16
|
+
end
|
17
|
+
|
18
|
+
task default: :test
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Eivid
|
2
|
+
class ApplicationController < API::BaseController
|
3
|
+
|
4
|
+
include Concerns::VideoValidations
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def set_owner
|
9
|
+
@owner = Owner.find_by(external_id: eval(Eivid.infer_external_owner_id)) || report_record_not_found
|
10
|
+
end
|
11
|
+
|
12
|
+
def report_record_not_found
|
13
|
+
raise MainAppRecordNotFoundError.new(
|
14
|
+
"The given external_owner_id could not be mapped to your application's owner records.
|
15
|
+
Beware: if you have overwritten the Eivid.infer_external_owner_id setting, the error is dependant on your main application."
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Eivid::Concerns::VideoValidations
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
included do
|
4
|
+
|
5
|
+
MAX_MB_VIDEO = 100
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def validate_video_file
|
10
|
+
validate_video_file_presence
|
11
|
+
validate_video_file_format
|
12
|
+
validate_video_file_size
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_video_file_presence
|
16
|
+
unless params["video_file"]
|
17
|
+
raise Eivid::VideoFileNotPresentError.new(
|
18
|
+
"you forgot to add a required 'video_file' to your request"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_video_file_format
|
24
|
+
mime = params["video_file"]&.original_filename&.split('.')&.last&.downcase
|
25
|
+
unless Eivid::VideoMimeDump::DATA.include?(mime)
|
26
|
+
raise Eivid::IncorrectVideoMimeTypeError.new(
|
27
|
+
"the 'video_file' you tried to upload, is of an invalid mime type"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_video_file_size
|
33
|
+
megabytes = params["video_file"].tempfile.size / 1.0.megabyte
|
34
|
+
unless MAX_MB_VIDEO >= megabytes
|
35
|
+
raise VideoFileSizeTooBigError.new(
|
36
|
+
"the 'video_file' size (#{megabytes.round(2)} mb) you tried to upload exceeds the maximum file size (#{MAX_MB_VIDEO} mb)"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_dependency "eivid/application_controller"
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
# for local development, run:
|
5
|
+
# QUEUE=* rake resque:work
|
6
|
+
# rake environment resque:scheduler
|
7
|
+
|
8
|
+
module Eivid
|
9
|
+
class VideosController < ApplicationController
|
10
|
+
|
11
|
+
before_action :set_owner, only: [:upload_video, :owner_videos]
|
12
|
+
before_action :set_video, only: [:show, :destroy]
|
13
|
+
before_action :validate_video_file, only: [:upload_video]
|
14
|
+
|
15
|
+
def upload_video
|
16
|
+
record = UploadService.upload(owner: @owner, user: @user, video_file: video_params["video_file"])
|
17
|
+
render json: record
|
18
|
+
end
|
19
|
+
|
20
|
+
def owner_videos
|
21
|
+
render json: @owner.videos
|
22
|
+
end
|
23
|
+
|
24
|
+
def index
|
25
|
+
render json: Video.all
|
26
|
+
end
|
27
|
+
|
28
|
+
def show
|
29
|
+
render json: @video
|
30
|
+
end
|
31
|
+
|
32
|
+
def destroy
|
33
|
+
record = RequestService.destroy(video: @video)
|
34
|
+
render json: record
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def set_video
|
40
|
+
@video = Video.find params["id"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def video_params
|
44
|
+
params.permit("video_file")
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Eivid
|
2
|
+
class CheckVimeoStatusJob < ApplicationJob
|
3
|
+
|
4
|
+
retry_on VideoUnavailableError, wait: 10.seconds, attempts: 50
|
5
|
+
after_perform :poll_vimeo_urls
|
6
|
+
|
7
|
+
def perform(video_record:)
|
8
|
+
@video_record = video_record
|
9
|
+
|
10
|
+
set_vimeo_id
|
11
|
+
set_video_status
|
12
|
+
|
13
|
+
upload_completed ? notify_front : (raise Eivid::VideoUnavailableError)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def set_vimeo_id
|
19
|
+
@vimeo_id ||= @video_record.url_embedded.split('/').last
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_video_status
|
23
|
+
@video_status = Eivid::RequestService.get_status(vimeo_id: @vimeo_id)["status"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def upload_completed
|
27
|
+
@video_status == "available"
|
28
|
+
end
|
29
|
+
|
30
|
+
def notify_front
|
31
|
+
data = { video: @video_record.slice(:id, :user_id), progress: { percentage: 66, step: "The video is available on Vimeo." } }
|
32
|
+
NotifyFrontService.progress('notify_method_on_video_available', data)
|
33
|
+
end
|
34
|
+
|
35
|
+
def report_max_poll
|
36
|
+
raise MaximumVimeoPollReachedError.new (
|
37
|
+
"the maximum amount of polling Vimeo (#{@@maximum_vimeo_polls} times) for the status of Eivid::Video ##{@video_record&.id} is reached."
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def poll_vimeo_urls
|
42
|
+
GetVimeoUrlsJob.perform_later(video_record: @video_record, vimeo_id: @vimeo_id)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|