Compare commits

...

47 Commits

Author SHA1 Message Date
Bilal
14445aeb14 do not use remember_me, set cookie expiration 2020-08-25 05:25:16 +02:00
Bilal
01da597f3e modify specs 2020-08-25 05:25:16 +02:00
Bilal
663a6d5c33 add remember_me token 2020-08-25 05:25:16 +02:00
Senad Uka
896cec2259 Upstream sync 2020-08-25 05:24:49 +02:00
Senad Uka
a493076f9b Upstream sync 2020-08-24 15:52:23 +02:00
Senad Uka
41bf88e358 Upstream sync 2020-08-20 06:50:51 +02:00
Senad Uka
190ff2854b Upstream sync 2020-08-06 16:56:40 +00:00
Senad Uka
8214ba9e67 Changes 2020-08-03 21:52:04 +00:00
Senad Uka
9cbd8d31a8 Upstream sync 2020-07-29 05:15:02 +00:00
Senad Uka
9c3fac4ab9 Upstream sync 2020-07-27 10:17:56 +00:00
Senad Uka
8f13589c55 upstream sync 2020-07-22 19:14:34 +00:00
Senad Uka
cd0de9154c Upstream sync 2020-07-22 13:38:19 +00:00
Senad Uka
2590b6bdc9 Upstream sync 2020-07-21 13:12:27 +00:00
Senad Uka
40f241b75f Usptream sync 2020-07-20 13:28:40 +00:00
Senad Uka
add8304eab Master upstream sync 2020-07-16 18:02:45 +02:00
Senad Uka
f04d34d337 Upstream sync 2020-07-16 17:38:21 +02:00
Senad Uka
c033f5df17 Upstream sync 2020-07-16 17:27:57 +02:00
Senad Uka
7f49f31ebf Master sync 2020-07-15 11:58:34 +02:00
Senad Uka
4c49a5db03 Upstream sync 2020-07-14 14:10:30 +02:00
Senad Uka
35303cb570 Upstream sync 2020-07-09 11:06:17 +02:00
Senad Uka
1127f09263 Upstream sync 2020-07-08 18:27:49 +02:00
Senad Uka
19b1e75384 Upstream sync 2020-07-07 23:14:42 +02:00
Senad Uka
93a4ce462d Upstream sync 2020-07-07 21:45:30 +02:00
Senad Uka
0e16791d8b Upstream sync 2020-07-07 05:08:32 +02:00
Senad Uka
7cdb814d6d Upstream sync 2020-07-06 10:22:04 +02:00
Senad Uka
2dea0f29b9 Upstream sync 2020-07-03 10:23:03 +02:00
Senad Uka
d6a3542308 Upstream sync 2020-07-02 10:34:24 +02:00
Senad Uka
e49498bbbf Upstream sync 2020-07-01 06:39:02 +02:00
Senad Uka
dd0ac5b110 Upstream sync 2020-06-30 05:07:43 +02:00
Senad Uka
8951667e61 Upstrream sync 2020-06-26 18:45:11 +02:00
Senad Uka
fe131491cd Upstream sync 2020-06-26 04:55:50 +02:00
Senad Uka
290dbfa48b Upstream sync 2020-06-25 08:46:11 +02:00
Senad Uka
319cd89b29 Upstream sync 2020-06-24 04:48:12 +02:00
Senad Uka
6b0ea5b7df Upstream sync 2020-06-23 17:10:53 +02:00
Senad Uka
afee9d9bc9 Upstream sync 2020-06-22 20:28:22 +02:00
Senad Uka
072142811f Upstream sync 2020-06-22 14:14:25 +02:00
Senad Uka
b924b99762 Upstream sync 2020-06-19 09:23:07 +02:00
Senad Uka
988ef2beab Upstream sync 2020-06-18 17:51:08 +02:00
Senad Uka
1168bcdfdd Upstream sync 2020-06-18 16:56:11 +02:00
Senad Uka
a7b90c223b Upstream sync 2020-06-17 14:39:10 +02:00
Senad Uka
9a540efc74 Upstream sync 2020-06-16 17:11:04 +02:00
Senad Uka
028e946fcf Upstream sync 2020-06-15 08:33:23 +02:00
Senad Uka
fbf3173747 Upstream sync 2020-06-12 16:38:59 +02:00
Senad Uka
5f5e6c18b5 Upstream sync 2020-06-11 16:56:29 +02:00
Senad Uka
dc9ba08e1b Upstream sync 2020-06-10 11:19:35 +02:00
Senad Uka
cd5bbaeb62 Upstream sync master 2020-06-09 06:35:40 +02:00
Senad Uka
64bda6eab6 Upstream sync 2020-06-03 17:14:04 +02:00
437 changed files with 15370 additions and 1537 deletions

View File

@@ -7,8 +7,6 @@ AWS_SECRET_ACCESS_KEY=
AWS_REGION= AWS_REGION=
BRAYNIAC_AI_API_ENDPOINT=https://z99cprg2eg.execute-api.us-east-1.amazonaws.com/dev/v0.0.1 BRAYNIAC_AI_API_ENDPOINT=https://z99cprg2eg.execute-api.us-east-1.amazonaws.com/dev/v0.0.1
SOURCE_AUDIO_API_ENDPOINT=https://bigmedia.sourceaudio.com/api
SOURCE_AUDIO_TOKEN=
# Optional # Optional
REDIS_URL= REDIS_URL=
@@ -18,7 +16,7 @@ ZOOM_API_KEY=
ZOOM_API_SECRET= ZOOM_API_SECRET=
ZOOM_PRO_USERS_LIMIT= # defaults to 3 ZOOM_PRO_USERS_LIMIT= # defaults to 3
ZOOM_USER_TYPE= # 'pro' / 'basic' ZOOM_USER_TYPE= # 'pro' / 'basic'
ZOOM_ENABLE_RECORDINGS=0 # 0 / 1 ZOOM_ENABLE_RECORDINGS= # true / false (default: false)
# Token for webhooks authorization # Token for webhooks authorization
ZOOM_VERIFICATION_TOKEN= ZOOM_VERIFICATION_TOKEN=
@@ -27,3 +25,10 @@ MUX_TOKEN_ID=
MUX_TOKEN_SECRET= MUX_TOKEN_SECRET=
MUX_BROADCAST_SERVER_URL=rtmp://global-live.mux.com:5222/app MUX_BROADCAST_SERVER_URL=rtmp://global-live.mux.com:5222/app
MUX_TEST_MODE_DISABLED= MUX_TEST_MODE_DISABLED=
# Required for creating user through API
CUSTOM_API_TOKEN=
# Required for simulcasting to Millicast for director mode
MILLICAST_API_SECRET=
MILLICAST_ACCOUNT_ID=

View File

@@ -4,7 +4,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "2.6.3" ruby "2.6.3"
# Bundle edge Rails instead: gem "rails", github: "rails/rails" # Bundle edge Rails instead: gem "rails", github: "rails/rails"
gem "rails", "~> 6.0.0" gem "rails", "~> 6.0.3.1"
# Use postgresql as the database for Active Record # Use postgresql as the database for Active Record
gem "pg", "~> 0.18" gem "pg", "~> 0.18"
# Use Puma as the app server # Use Puma as the app server
@@ -30,9 +30,9 @@ gem "active_storage_base64", "~> 1.0.0"
gem "image_processing", "~> 1.2" gem "image_processing", "~> 1.2"
# Use Amazon Web Services S3 for file uploads in production # Use Amazon Web Services S3 for file uploads in production
gem "aws-sdk-s3", "~> 1.31.0", require: false, group: [:production, :review] gem "aws-sdk-s3", "~> 1.48", require: false, group: [:production, :review]
# Allow AWS API requests to be signed using IAM credentials # Allow AWS API requests to be signed using IAM credentials
gem "aws-sigv4", "~> 1.0.2" gem "aws-sigv4", "~> 1.1"
# Reduces boot times through caching; required in config/boot.rb # Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", ">= 1.1.0", require: false gem "bootsnap", ">= 1.1.0", require: false

View File

@@ -44,71 +44,71 @@ GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
Ascii85 (1.0.3) Ascii85 (1.0.3)
actioncable (6.0.0) actioncable (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
nio4r (~> 2.0) nio4r (~> 2.0)
websocket-driver (>= 0.6.1) websocket-driver (>= 0.6.1)
actionmailbox (6.0.0) actionmailbox (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
activejob (= 6.0.0) activejob (= 6.0.3.2)
activerecord (= 6.0.0) activerecord (= 6.0.3.2)
activestorage (= 6.0.0) activestorage (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
mail (>= 2.7.1) mail (>= 2.7.1)
actionmailer (6.0.0) actionmailer (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
actionview (= 6.0.0) actionview (= 6.0.3.2)
activejob (= 6.0.0) activejob (= 6.0.3.2)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
actionpack (6.0.0) actionpack (6.0.3.2)
actionview (= 6.0.0) actionview (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
rack (~> 2.0) rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (6.0.0) actiontext (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
activerecord (= 6.0.0) activerecord (= 6.0.3.2)
activestorage (= 6.0.0) activestorage (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
nokogiri (>= 1.8.5) nokogiri (>= 1.8.5)
actionview (6.0.0) actionview (6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
builder (~> 3.1) builder (~> 3.1)
erubi (~> 1.4) erubi (~> 1.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0)
active_storage_base64 (1.0.0) active_storage_base64 (1.0.0)
rails (~> 6.0) rails (~> 6.0)
activejob (6.0.0) activejob (6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
globalid (>= 0.3.6) globalid (>= 0.3.6)
activemodel (6.0.0) activemodel (6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
activemodel-serializers-xml (1.0.2) activemodel-serializers-xml (1.0.2)
activemodel (> 5.x) activemodel (> 5.x)
activesupport (> 5.x) activesupport (> 5.x)
builder (~> 3.1) builder (~> 3.1)
activerecord (6.0.0) activerecord (6.0.3.2)
activemodel (= 6.0.0) activemodel (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
activeresource (5.1.0) activeresource (5.1.0)
activemodel (>= 5.0, < 7) activemodel (>= 5.0, < 7)
activemodel-serializers-xml (~> 1.0) activemodel-serializers-xml (~> 1.0)
activesupport (>= 5.0, < 7) activesupport (>= 5.0, < 7)
activestorage (6.0.0) activestorage (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
activejob (= 6.0.0) activejob (= 6.0.3.2)
activerecord (= 6.0.0) activerecord (= 6.0.3.2)
marcel (~> 0.3.1) marcel (~> 0.3.1)
activesupport (6.0.0) activesupport (6.0.3.2)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
minitest (~> 5.1) minitest (~> 5.1)
tzinfo (~> 1.1) tzinfo (~> 1.1)
zeitwerk (~> 2.1, >= 2.1.8) zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.7.0) addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
afm (0.2.2) afm (0.2.2)
@@ -117,21 +117,22 @@ GEM
ast (2.4.0) ast (2.4.0)
autoprefixer-rails (9.7.3) autoprefixer-rails (9.7.3)
execjs execjs
aws-eventstream (1.0.3) aws-eventstream (1.1.0)
aws-partitions (1.210.0) aws-partitions (1.337.0)
aws-sdk-core (3.46.2) aws-sdk-core (3.102.1)
aws-eventstream (~> 1.0) aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1.0) aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.0) aws-sigv4 (~> 1.1)
jmespath (~> 1.0) jmespath (~> 1.0)
aws-sdk-kms (1.13.0) aws-sdk-kms (1.35.0)
aws-sdk-core (~> 3, >= 3.39.0) aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.0) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.31.0) aws-sdk-s3 (1.72.0)
aws-sdk-core (~> 3, >= 3.39.0) aws-sdk-core (~> 3, >= 3.102.1)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.0) aws-sigv4 (~> 1.1)
aws-sigv4 (1.0.3) aws-sigv4 (1.2.1)
aws-eventstream (~> 1, >= 1.0.2)
axlsx (3.0.0.pre) axlsx (3.0.0.pre)
htmlentities (~> 4.3, >= 4.3.4) htmlentities (~> 4.3, >= 4.3.4)
mimemagic (~> 0.3) mimemagic (~> 0.3)
@@ -181,7 +182,7 @@ GEM
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.12.2) coffee-script-source (1.12.2)
concurrent-ruby (1.1.5) concurrent-ruby (1.1.6)
connection_pool (2.2.2) connection_pool (2.2.2)
countries (2.1.4) countries (2.1.4)
i18n_data (~> 0.8.0) i18n_data (~> 0.8.0)
@@ -230,7 +231,7 @@ GEM
hubspot-ruby (0.9.0) hubspot-ruby (0.9.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
httparty (>= 0.10.0) httparty (>= 0.10.0)
i18n (1.8.2) i18n (1.8.3)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
i18n_data (0.8.0) i18n_data (0.8.0)
i18n_yaml_sorter (0.2.0) i18n_yaml_sorter (0.2.0)
@@ -270,22 +271,22 @@ GEM
ruby_dep (~> 1.2) ruby_dep (~> 1.2)
loaf (0.8.1) loaf (0.8.1)
rails (>= 3.2) rails (>= 3.2)
loofah (2.4.0) loofah (2.6.0)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.7.1) mail (2.7.1)
mini_mime (>= 0.1.1) mini_mime (>= 0.1.1)
marcel (0.3.3) marcel (0.3.3)
mimemagic (~> 0.3.2) mimemagic (~> 0.3.2)
method_source (0.9.2) method_source (1.0.0)
mime-types (3.3) mime-types (3.3)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2019.0904) mime-types-data (3.2019.0904)
mimemagic (0.3.3) mimemagic (0.3.5)
mini_magick (4.9.5) mini_magick (4.9.5)
mini_mime (1.0.2) mini_mime (1.0.2)
mini_portile2 (2.4.0) mini_portile2 (2.4.0)
minitest (5.14.0) minitest (5.14.1)
monetize (1.9.2) monetize (1.9.2)
money (~> 6.12) money (~> 6.12)
money (6.13.4) money (6.13.4)
@@ -298,8 +299,8 @@ GEM
msgpack (1.3.1) msgpack (1.3.1)
multi_xml (0.6.0) multi_xml (0.6.0)
multipart-post (2.1.1) multipart-post (2.1.1)
nio4r (2.5.1) nio4r (2.5.2)
nokogiri (1.10.7) nokogiri (1.10.9)
mini_portile2 (~> 2.4.0) mini_portile2 (~> 2.4.0)
oath (1.1.0) oath (1.1.0)
bcrypt bcrypt
@@ -337,20 +338,20 @@ GEM
rack rack
rack-test (1.1.0) rack-test (1.1.0)
rack (>= 1.0, < 3) rack (>= 1.0, < 3)
rails (6.0.0) rails (6.0.3.2)
actioncable (= 6.0.0) actioncable (= 6.0.3.2)
actionmailbox (= 6.0.0) actionmailbox (= 6.0.3.2)
actionmailer (= 6.0.0) actionmailer (= 6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
actiontext (= 6.0.0) actiontext (= 6.0.3.2)
actionview (= 6.0.0) actionview (= 6.0.3.2)
activejob (= 6.0.0) activejob (= 6.0.3.2)
activemodel (= 6.0.0) activemodel (= 6.0.3.2)
activerecord (= 6.0.0) activerecord (= 6.0.3.2)
activestorage (= 6.0.0) activestorage (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
bundler (>= 1.3.0) bundler (>= 1.3.0)
railties (= 6.0.0) railties (= 6.0.3.2)
sprockets-rails (>= 2.0.0) sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.4) rails-controller-testing (1.0.4)
actionpack (>= 5.0.1.x) actionpack (>= 5.0.1.x)
@@ -363,9 +364,9 @@ GEM
nokogiri (>= 1.6) nokogiri (>= 1.6)
rails-html-sanitizer (1.3.0) rails-html-sanitizer (1.3.0)
loofah (~> 2.3) loofah (~> 2.3)
railties (6.0.0) railties (6.0.3.2)
actionpack (= 6.0.0) actionpack (= 6.0.3.2)
activesupport (= 6.0.0) activesupport (= 6.0.3.2)
method_source method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.20.3, < 2.0) thor (>= 0.20.3, < 2.0)
@@ -469,7 +470,7 @@ GEM
turbolinks-source (5.2.0) turbolinks-source (5.2.0)
typhoeus (1.3.1) typhoeus (1.3.1)
ethon (>= 0.9.0) ethon (>= 0.9.0)
tzinfo (1.2.6) tzinfo (1.2.7)
thread_safe (~> 0.1) thread_safe (~> 0.1)
uglifier (4.1.20) uglifier (4.1.20)
execjs (>= 0.3.0, < 3) execjs (>= 0.3.0, < 3)
@@ -494,9 +495,9 @@ GEM
activesupport (>= 4.2) activesupport (>= 4.2)
rack-proxy (>= 0.6.1) rack-proxy (>= 0.6.1)
railties (>= 4.2) railties (>= 4.2)
websocket-driver (0.7.1) websocket-driver (0.7.2)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.4) websocket-extensions (0.1.5)
will_paginate (3.2.1) will_paginate (3.2.1)
will_paginate-bootstrap4 (0.2.2) will_paginate-bootstrap4 (0.2.2)
will_paginate (~> 3.0, >= 3.0.0) will_paginate (~> 3.0, >= 3.0.0)
@@ -504,7 +505,7 @@ GEM
wkhtmltopdf-heroku (2.12.5.0) wkhtmltopdf-heroku (2.12.5.0)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
zeitwerk (2.2.2) zeitwerk (2.3.1)
PLATFORMS PLATFORMS
ruby ruby
@@ -514,8 +515,8 @@ DEPENDENCIES
activeresource (= 5.1.0) activeresource (= 5.1.0)
acts-as-taggable-on! acts-as-taggable-on!
analytics-ruby analytics-ruby
aws-sdk-s3 (~> 1.31.0) aws-sdk-s3 (~> 1.48)
aws-sigv4 (~> 1.0.2) aws-sigv4 (~> 1.1)
axlsx (~> 3.0.0.pre) axlsx (~> 3.0.0.pre)
axlsx_rails (~> 0.5.2) axlsx_rails (~> 0.5.2)
axlsx_styler (~> 0.2.0) axlsx_styler (~> 0.2.0)
@@ -561,7 +562,7 @@ DEPENDENCIES
rack! rack!
rack-contrib (~> 2.0.1) rack-contrib (~> 2.0.1)
rack-cors rack-cors
rails (~> 6.0.0) rails (~> 6.0.3.1)
rails-controller-testing (~> 1.0.4) rails-controller-testing (~> 1.0.4)
rails-data-migrations (~> 1.2.0) rails-data-migrations (~> 1.2.0)
redcarpet (~> 3.4.0) redcarpet (~> 3.4.0)

View File

@@ -95,14 +95,28 @@ rake i18n:sort
``` ```
## Zoom.us integration ## Zoom.us integration
DirectMe app offers live broadcasting. Users are offered to paralelly connect to the Zoom meeting to have a video conference while the streaming happens. In order to use the Zoom functionality, the app needs to have the API keys provided. You need Zoom PRO account for this feature. DirectMe app offers live broadcasting feature. Users are offered to paralelly connect to the Zoom meeting to have a video conference while the streaming happens. In order to use the Zoom functionality, the app needs to have the API and verification token keys provided along with the account number that is available after login into the Zoom account. You need to have Zoom PRO subscription in order to use this feature.
#### Zoom.us api keys #### Zoom.us api keys
1. Log in to you zoom.us account 1. Log in to you zoom.us account
2. Go to https://marketplace.zoom.us/develop/create 2. Go to https://marketplace.zoom.us/develop/create
3. Choose JWT application 3. Choose JWT application
4. Copy API Key and API Secret 4. Copy API Key and API Secret
5. Set up ZOOM_API_KEY and ZOOM_API_SECRET environment variables
#### Setup
There is some configuration that has to be done through the API on the Zoom account so that you can use the feature. Run `rails zoom:setup` rake task to do it.
#### Zoom.us webhooks
To ensure integrity in between different Zoom environments, the app uses Zoom webhooks. To set them up, go to https://marketplace.czoom.us -> Develop -> JWT app -> Feature -> Event Subscriptions and enable following hooks:
* Start Meeting
* End Meeting
* All Recordings have completed
* User has been created
* User had been deleted
#### Syncing app with Zoom account configuration
If you are setting up the app to use Zoom account that has been previously used with DirectME, it is a good idea to make sure that the db state reflects the account situation. To do that, run `rails zoom:sync` rake task.
## Working Locally ## Working Locally

View File

@@ -1,45 +0,0 @@
$(document).on "turbolinks:load", ->
# Only connect if a broadcast-token meta tag is present
broadcast_meta = document.querySelector("meta[name=broadcast-token]")
return unless broadcast_meta
broadcastToken = broadcast_meta.getAttribute("content")
App.public = App.cable.subscriptions.create { channel: "BroadcastsChannel", token: broadcastToken },
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
return unless document.querySelector("meta[name=broadcast-token][content='#{broadcastToken}']")
switch data.event
when "broadcast_stream_update" then @refreshBroadcastVideo(data)
when "stream_recording_ready" then @showBroadcastRecordings(data)
when "file_upload_update" then @refreshFilesTab(data)
refreshBroadcastVideo: (data) ->
$("#broadcast_updates").html data.status_content
if data.streamer_status == 'recording' && data.status == 'active'
$("#broadcast_video").html data.video_content
new (Clappr.Player)(
parentId: '#broadcast_video'
source: data.playback_url
width: '100%',
height: '100%',
mute: true,
autoPlay: true,
hlsMinimumDvrSize: 1)
if data.streamer_status == "idle" && data.status == "idle"
$("#broadcast_video").html data.video_content
showBroadcastRecordings: (data) ->
$(".flash-message").html data.flash_content
$("#broadcast_recordings").html data.recordings_content
$("#broadcast_recordings_nav").html data.recordings_nav_content
refreshFilesTab: (data) ->
$("#broadcast_file_list").html data.files_content
$("#broadcast_files_pagination").html data.pagination_content

View File

@@ -0,0 +1,51 @@
$(document).on "turbolinks:load", ->
subscribeToBroadcast = (broadcastToken) -> App.cable.subscriptions.create { channel: "BroadcastsChannel", token: broadcastToken },
connected: ->
# Called when the subscription is ready for use on the server
console.info "Subscribed to channel for broadcast:#{broadcastToken}"
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
switch data.event
when "broadcast_stream_update"
return unless document.querySelector("meta[name=broadcast-token][current=true][content='#{broadcastToken}']")
@refreshBroadcastVideo(data)
when "stream_recording_ready"
return unless document.querySelector("meta[name=broadcast-token][current=true][content='#{broadcastToken}']")
@showBroadcastRecordings(data)
when "file_upload_update"
return unless document.querySelector("meta[name=broadcast-token][content='#{broadcastToken}']")
@refreshBroadcastFilesTab(data)
refreshBroadcastVideo: (data) ->
$("#broadcast_updates").html data.status_content
stream_selected = $("#broadcast_video").data('videoType') == 'stream';
if data.streamer_status == 'recording' && data.status == 'active' && stream_selected
$("#broadcast_video").html data.video_content
new (Clappr.Player)(
<%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %>
parentId: '#broadcast_video'
source: data.full_live_stream_playback_url
width: '100%',
height: '100%',
mute: true,
autoPlay: true,
hlsMinimumDvrSize: 1)
if data.streamer_status == "idle" && data.status == "idle"
$("#broadcast_video").html data.video_content
showBroadcastRecordings: (data) ->
$(".flash-message").html data.flash_content
$("#broadcast_recordings").html data.recordings_content
$("#broadcast_recordings_nav").html data.recordings_nav_content
refreshBroadcastFilesTab: (data) ->
$("#broadcast_file_list_#{data.broadcast_token}").html data.files_content
$("#broadcast_files_pagination_#{data.broadcast_token}").html data.pagination_content
# Create a channel subscription for every broadcast included in the meta tags
get_token = (meta) -> meta.getAttribute("content")
broadcast_tokens = (get_token broadcast_meta for broadcast_meta in document.querySelectorAll("meta[name=broadcast-token]"))
subscribeToBroadcast token for token in broadcast_tokens

View File

@@ -1,11 +1,16 @@
$(document).on("change", "[data-toggle=collapse-select]", function(event) { $(document).on("change", "[data-toggle=collapse-select]", function(event) {
const select = event.target; const select = event.target;
const target = select.dataset.target; const mappings = JSON.parse(select.dataset.targetShowValuesMapping);
const showValues = JSON.parse(select.dataset.showValues);
$.each(mappings, function( key, value ) {
if (showValues.indexOf(select.value) > -1) { if (value.indexOf(select.value) > -1) {
$(target).show("fast"); $(key).show("fast");
} else { } else {
$(target).hide("fast"); $(key).hide("fast");
} }
});
}); });
$(document).on("turbolinks:load", function() {
$("[data-toggle=collapse-select]").trigger("change");
});

View File

@@ -0,0 +1,9 @@
$(document).on("turbolinks:load", function() {
$("#upload_directory_files").on('click', function(e){
const newFilesCount = $('input[name = "directory[files][]"][type = "hidden"]').length;
if (newFilesCount === 0){
e.preventDefault();
}
});
});

View File

@@ -0,0 +1,50 @@
$(document).on("click", "[data-behavior=select_contract_template]", function() {
var _this = this;
var checkbox = $(this).children("input:checkbox");
selectContractTemplate(_this, checkbox);
});
$(document).on("click", "[data-behavior=select_contract_template] input[type='checkbox']", function(e) {
e.stopPropagation();
var _this = this;
var checkbox = $(this);
selectContractTemplate(_this, checkbox);
});
function selectContractTemplate(clicked_element, checkbox) {
if (clicked_element.hasChildNodes()) {
if(checkbox.prop("checked")) {
checkbox.prop('checked', false);
} else {
checkbox.prop('checked', true);
}
}
var checked = checkbox.prop("checked");
var project_id = JSON.parse($('#group_qr_code').attr('data-project-id'));
var contract_template_ids = JSON.parse($('#group_qr_code').attr('data-contract-template-ids'));
var selected_contract_template_id = checkbox.val();
if (checked && !contract_template_ids.includes(selected_contract_template_id)) {
contract_template_ids.push(selected_contract_template_id);
} else if(!checked && contract_template_ids.includes(selected_contract_template_id)) {
contract_template_ids.splice( $.inArray(selected_contract_template_id, contract_template_ids), 1 );
}
$('#group_qr_code').attr('data-contract-template-ids', JSON.stringify(contract_template_ids));
if (contract_template_ids.length >= 2) {
multi_sign_ids = $.param({multi_sign_ids: contract_template_ids});
contract_template_url = "/en/contract_templates/" + contract_template_ids[0] + "/qr_codes?" + multi_sign_ids
$("#group_qr_code").attr("href", contract_template_url);
$("#group_qr_code").attr("target", "_blank");
$("#group_qr_code").removeClass('disabled');
} else if (contract_template_ids.length < 2) {
$("#group_qr_code").attr("href", "javascript:void(0);");
$("#group_qr_code").addClass('disabled');
}
}

View File

@@ -39,7 +39,7 @@ function selectBroadcast(clicked_element, checkbox) {
if (broadcast_ids.length >= 2) { if (broadcast_ids.length >= 2) {
multi_view_ids = $.param({multi_view_ids: broadcast_ids}); multi_view_ids = $.param({multi_view_ids: broadcast_ids});
broadcast_url = "/en/projects/" + project_id + "/broadcasts/" + broadcast_ids[0] + "?" + multi_view_ids broadcast_url = "/en/projects/" + project_id + "/broadcasts/" + broadcast_ids[0] + "?" + multi_view_ids
$("#multi_view_broadcasts").attr("href", broadcast_url); $("#multi_view_broadcasts").attr("href", broadcast_url);
$("#multi_view_broadcasts").attr("target", "_blank"); $("#multi_view_broadcasts").attr("target", "_blank");
$("#multi_view_broadcasts").removeClass('disabled'); $("#multi_view_broadcasts").removeClass('disabled');

View File

@@ -51,10 +51,8 @@ $(document).on("turbolinks:load", function() {
$("[data-behavior=guardian-photo-preview]").each(function(index, element) { $("[data-behavior=guardian-photo-preview]").each(function(index, element) {
App.PhotoPreview.init(element); App.PhotoPreview.init(element);
}); });
$("[data-behavior=take-person-photo]").click(function(e) { $("[data-behavior=trigger-click]").click(function(e) {
$("[data-ujs-target=person-photo-input]").trigger("click"); const target = $(this).data("target");
}); $(target).trigger("click");
$("[data-behavior=take-guardian-photo]").click(function(e) {
$("[data-ujs-target=guardian-photo-input]").trigger("click");
}); });
}); });

View File

@@ -1,24 +0,0 @@
$(document).on("click", "[data-behavior=play_recording]", function() {
if ($(this).hasClass('active')){
return false;
}
var playback_url = $(this).attr("data-playback-url")
$("#broadcast_video").empty();
new Clappr.Player({
parentId: '#broadcast_video',
source: playback_url,
width: '100%',
height: '100%',
autoPlay: true
});
$(".dropdown-menu").children().removeClass('active');
$(".dropdown-menu").children().children('i').remove();
$(this).siblings().removeClass('active');
$(this).siblings().children("i").remove();
$(this).addClass('active');
$(this).prepend('<i class="fa fa-check">&nbsp;</i>');
});

View File

@@ -0,0 +1,28 @@
$(document).on("click", "[data-behavior=play_recording]", function() {
if ($(this).hasClass('active')){
return false;
}
$("#broadcast_video").data('videoType', 'recording');
var playback_url = $(this).attr("data-playback-url")
$("#broadcast_video").empty();
new Clappr.Player({
<%= "baseUrl: 'http://cdn.clappr.io/latest'," if Rails.env.test? %>
parentId: '#broadcast_video',
source: playback_url,
width: '100%',
height: '100%',
autoPlay: true
});
$(".dropdown-menu").children().removeClass('active');
$(".dropdown-menu").children().children('i').remove();
$(this).siblings().removeClass('active');
$(this).siblings().children("i").remove();
$(this).addClass('active');
$(this).prepend('<i class="fa fa-check">&nbsp;</i>');
});
$(document).on("click", "[data-behavior=play_stream]", function() { $("#broadcast_video").data('videoType', 'stream'); });

View File

@@ -0,0 +1,13 @@
$(document).on("turbolinks:load", function() {
$("[data-behavior=update-required-status]").click(function(e) {
const required = !!($(this)[0] && $(this)[0].checked);
$("[data-required-tag=guardian]").each(function(index, element) {
const labelForField = element.previousSibling;
element.required = required;
labelForField.classList.add("required");
});
});
});

View File

@@ -14,6 +14,7 @@ $red: #F9002B;
$green: #51B61B; $green: #51B61B;
$teal: #32C498; $teal: #32C498;
$purple: #5139EE; $purple: #5139EE;
$yellow: #F9BE1B;
$dark: $gray-900; $dark: $gray-900;
$success: $teal; $success: $teal;
$link-color: $body-color; $link-color: $body-color;

View File

@@ -6,6 +6,11 @@
@import "dropzone/dist/dropzone"; @import "dropzone/dist/dropzone";
@import 'bootstrap-datepicker'; @import 'bootstrap-datepicker';
// Global styles
label {
text-transform: capitalize;
}
// Wordmarks // Wordmarks
.suite-wordmark { .suite-wordmark {
font-weight: normal; font-weight: normal;
@@ -32,14 +37,14 @@
&.release-me { &.release-me {
span:last-child { span:last-child {
background-color: $teal; background-color: $teal;
color: $body-color; color: $white;
} }
} }
&.direct-me { &.direct-me {
span:last-child { span:last-child {
background-color: $green; background-color: $green;
color: $body-color; color: $white;
} }
} }
@@ -53,7 +58,14 @@
&.deliver-me { &.deliver-me {
span:last-child { span:last-child {
background-color: $purple; background-color: $purple;
color: white; color: $white;
}
}
&.task-me {
span:last-child {
background-color: $yellow;
color: $white;
} }
} }

View File

@@ -31,7 +31,7 @@ u {
} }
.page { .page {
page-break-before: always; page-break-before: always;
} }
.logo { .logo {
@@ -44,6 +44,14 @@ u {
text-align: right; text-align: right;
} }
.qr-code {
margin-right: -30px;
}
.do-not-copy-warning {
padding-right: 15px;
}
.heading-table td { .heading-table td {
width: 50%; width: 50%;
} }

View File

@@ -16,6 +16,7 @@ class BroadcastsChannel < ApplicationCable::Channel
event: :broadcast_stream_update, event: :broadcast_stream_update,
status: broadcast.status, status: broadcast.status,
playback_url: broadcast.stream_playback_url, playback_url: broadcast.stream_playback_url,
full_live_stream_playback_url: broadcast.full_live_stream_playback_url,
video_content: video_content, video_content: video_content,
status_content: status_content, status_content: status_content,
streamer_status: broadcast.streamer_status streamer_status: broadcast.streamer_status
@@ -35,11 +36,12 @@ class BroadcastsChannel < ApplicationCable::Channel
recordings_nav_content: recordings_nav_content recordings_nav_content: recordings_nav_content
end end
def self.file_upload_updates(broadcast, files, pagination_content) def self.broadcast_file_upload_updates(broadcast, files, pagination_content)
files_content = ApplicationController.render partial: "broadcasts/file", collection: files files_content = ApplicationController.render partial: "broadcasts/file", collection: files
broadcast_to broadcast, { broadcast_to broadcast, {
event: :file_upload_update, event: :file_upload_update,
broadcast_token: broadcast.token,
files_content: files_content, files_content: files_content,
pagination_content: pagination_content pagination_content: pagination_content
} }

View File

@@ -17,7 +17,7 @@ class AccountsController < ApplicationController
if sign_in(user) if sign_in(user)
TrackAnalyticsJob.perform_later(user, user.primary_account, :track_guest_sign_up, user_agent: request.user_agent, user_ip: request.remote_ip) TrackAnalyticsJob.perform_later(user, user.primary_account, :track_guest_sign_up, user_agent: request.user_agent, user_ip: request.remote_ip)
SubmitHubspotFormJob.perform_later(user.email, account.name, i_m_interested_in: user.interested_product_name) SubmitHubspotFormJob.perform_later(user.first_name, user.last_name, user.email, account.name, i_m_interested_in: user.interested_product_name)
redirect_to signed_in_root_path redirect_to signed_in_root_path
else else
redirect_to new_session_path, alert: t(".notice") redirect_to new_session_path, alert: t(".notice")

View File

@@ -18,7 +18,6 @@ class AcquiredMediaReleasesController < ApplicationController
@acquired_media_release = build_acquired_media_release(acquired_media_release_params) @acquired_media_release = build_acquired_media_release(acquired_media_release_params)
if @acquired_media_release.save if @acquired_media_release.save
log_create_analytics
SetTagsForReleasableJob.perform_later(@acquired_media_release) SetTagsForReleasableJob.perform_later(@acquired_media_release)
redirect_to [@project, :acquired_media_releases], notice: t(".notice") redirect_to [@project, :acquired_media_releases], notice: t(".notice")
else else
@@ -56,34 +55,71 @@ class AcquiredMediaReleasesController < ApplicationController
end end
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_company
person_email
person_title
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def acquired_media_release_params def acquired_media_release_params
params.require(:acquired_media_release).permit( params.require(:acquired_media_release).permit(person_params,
:name, guardian_params,
:territory, second_guardian_params,
:term, :minor,
:person_name, :name,
:person_phone, :territory,
:person_email, :term,
:person_company, :contract,
:person_title, :applicable_medium_id, :applicable_medium_text,
:person_address_street1, :territory_id, :territory_text,
:person_address_street2, :term_id, :term_text,
:person_address_city, :restriction_id, :restriction_text,
:person_address_state, categories: [],
:person_address_zip, files: []
:person_address_country, )
:contract,
:applicable_medium_id, :applicable_medium_text,
:territory_id, :territory_text,
:term_id, :term_text,
:restriction_id, :restriction_text,
categories: [],
file_infos_attributes: [
:filename,
:content_type,
:byte_size
]
)
end end
def build_acquired_media_release(attrs = {}) def build_acquired_media_release(attrs = {})
@@ -99,8 +135,4 @@ class AcquiredMediaReleasesController < ApplicationController
results results
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_non_native_release, release_type: AcquiredMediaRelease.to_s, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -20,6 +20,7 @@ class Admin::AccountsController < Admin::ApplicationController
def show def show
@videos = filtered_account_videos.order(created_at: :desc, project_id: :desc).paginate(page: params[:page]) @videos = filtered_account_videos.order(created_at: :desc, project_id: :desc).paginate(page: params[:page])
@broadcasts = account_broadcasts.order(created_at: :desc, project_id: :desc).paginate(page: params[:page])
end end
def edit def edit
@@ -70,4 +71,8 @@ class Admin::AccountsController < Admin::ApplicationController
@account.videos @account.videos
end end
end end
def account_broadcasts
@account.broadcasts
end
end end

View File

@@ -0,0 +1,29 @@
class Admin::BroadcastsController < Admin::ApplicationController
before_action :set_broadcast, only: [:edit, :update]
def edit
end
def update
if @broadcast.update(broadcast_update_params)
redirect_to [:admin, @broadcast.project.account], notice: t(".notice")
else
render :edit
end
end
private
def set_broadcast
@broadcast = authorize policy_scope(Broadcast).find(params[:id])
end
def broadcast_update_params
params.require(:broadcast).permit(
:video_conference_url_override,
:stream_url_override,
:stream_key_override,
:director_mode_video_embed
)
end
end

View File

@@ -0,0 +1,36 @@
class Admin::TaskRequestsController < Admin::ApplicationController
before_action :set_task_request, only: [:edit, :update, :show]
def index
@task_requests = task_requests.order_by_recent.paginate(page: params[:page])
end
def edit
end
def show
@files = @task_request.files.paginate(page: params[:page])
end
def update
if @task_request.update(task_request_params)
redirect_to [:admin, :task_requests], notice: t(".notice")
else
render :edit
end
end
private
def task_request_params
params.require(:task_request).permit(:status, :deliverable_url)
end
def task_requests
policy_scope TaskRequest
end
def set_task_request
@task_request = authorize policy_scope(TaskRequest).find(params[:id])
end
end

View File

@@ -17,7 +17,9 @@ class Api::ApiController < ActionController::Base
def return_error(exception) def return_error(exception)
raise exception if Rails.env.test? raise exception if Rails.env.test?
logger.error "==Handled=======" Raven.capture_exception(exception)
logger.error "==Handled======"
logger.error exception.message logger.error exception.message
logger.error exception.backtrace.join("\n") logger.error exception.backtrace.join("\n")
logger.error "==Handled=======" logger.error "==Handled======="

View File

@@ -19,5 +19,11 @@ class Api::AppearanceReleasesController < Api::ReleasesController
guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io])) guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io]))
release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename]) release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename])
end end
guardian_2_photo = release_create_params[:guardian_2_photo]
if guardian_2_photo
guardian_2_photo[:io] = StringIO.new(Base64.decode64(guardian_2_photo[:io]))
release.guardian_2_photo.attach(io: guardian_2_photo[:io], filename: guardian_2_photo[:filename])
end
end end
end end

View File

@@ -24,8 +24,12 @@ class Api::BroadcastsController < Api::ApiController
def update def update
file_params.each do |file| file_params.each do |file|
file[:io] = StringIO.new(Base64.decode64(file[:io])) if file.is_a?(String)
@broadcast.files.attach(io: file[:io], filename: file[:filename]) @broadcast.files.attach(file)
else
file[:io] = StringIO.new(Base64.decode64(file[:io]))
@broadcast.files.attach(file.to_h.symbolize_keys)
end
end end
@broadcast.save! @broadcast.save!

View File

@@ -0,0 +1,50 @@
# Duplicated from ActiveStorage::DirectUploadsController
# https://github.com/rails/rails/blob/v6.0.0/activestorage/app/controllers/active_storage/direct_uploads_controller.rb
class Api::DirectUploadsController < Api::ApiController
include ActiveStorage::SetCurrent
deserializable_resource :direct_upload, only: [:create]
def create
blob = ActiveStorage::Blob.create_before_direct_upload!(blob_params)
render jsonapi: DirectUpload.new(blob)
end
private
def blob_params
params.
require(:direct_upload).
permit(:type, :filename, :byte_size, :checksum, :content_type, :metadata).
except(:type).
to_h.symbolize_keys
end
class DeserializableDirectUpload < JSONAPI::Deserializable::Resource
attributes :filename, :byte_size, :checksum, :content_type, :metadata
end
class SerializableDirectUpload < JSONAPI::Serializable::Resource
type 'direct_upload'
attributes :id, :key, :signed_id, :url, :headers
end
class DirectUpload
delegate :id, :key, :signed_id, to: :blob
attr_reader :blob
def initialize(blob)
@blob = blob
end
def url
blob.service_url_for_direct_upload
end
def headers
blob.service_headers_for_direct_upload
end
end
end

View File

@@ -0,0 +1,11 @@
class Api::MedicalReleasesController < Api::ReleasesController
deserializable_resource :medical_release, only: [:create, :update]
def model_name
"medical_release"
end
def attributes_for_index
[:name]
end
end

View File

@@ -0,0 +1,11 @@
class Api::MiscReleasesController < Api::ReleasesController
deserializable_resource :misc_release, only: [:create, :update]
def model_name
"misc_release"
end
def attributes_for_index
[:name]
end
end

View File

@@ -21,7 +21,6 @@ class Api::ReleasesController < Api::ApiController
release.contract_template_id = @contract_template.id release.contract_template_id = @contract_template.id
handle_attachments(release, release_create_params[:photos]) handle_attachments(release, release_create_params[:photos])
release.save!(context: :native) release.save!(context: :native)
log_create_analytics
after_create(release) after_create(release)
handle_response(release, :created) handle_response(release, :created)
end end
@@ -103,10 +102,16 @@ class Api::ReleasesController < Api::ApiController
if ["appearance_release", "talent_release"].include?(name) if ["appearance_release", "talent_release"].include?(name)
has_many :guardian_photos do has_many :guardian_photos do
data do data do
[@object.guardian_photo.try(:attachment)].compact [
@object.guardian_photo.try(:attachment),
@object.guardian_2_photo.try(:attachment)
].compact
end end
meta do meta do
{ count: @object.try(:guardian_photo).try(:attached?) ? 1 : 0 } { count:
(@object.try(:guardian_photo).try(:attached?) ? 1 : 0) +
(@object.try(:guardian_2_photo).try(:attached?) ? 1 : 0)
}
end end
end end
end end
@@ -170,13 +175,9 @@ class Api::ReleasesController < Api::ApiController
def release_create_params def release_create_params
parameters = params.require(model_name).permit! parameters = params.require(model_name).permit!
keys = model_constant.new.attributes.keys + [:guardian_photo, :person_photo, :photos, :signature, :signature_base64, :file_infos_attributes] keys = model_constant.new.attributes.keys + [:guardian_photo, :guardian_2_photo, :person_photo, :photos, :signature, :signature_base64, :file_infos_attributes]
parameters[:signature_base64] = parameters[:signature] parameters[:signature_base64] = parameters[:signature]
parameters = parameters.slice(*keys).except(:created_at, :updated_at, :id, :user_id, :signature) parameters = parameters.slice(*keys).except(:created_at, :updated_at, :id, :user_id, :signature)
parameters parameters
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_native_release, release_type: model_constant.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip, application: :ios)
end
end end

View File

@@ -10,8 +10,10 @@ class Api::SyncController < Api::ApiController
@appearance_releases = (AppearanceRelease.where(project: accessible_projects)) @appearance_releases = (AppearanceRelease.where(project: accessible_projects))
@location_releases = (LocationRelease.where(project: accessible_projects)) @location_releases = (LocationRelease.where(project: accessible_projects))
@material_releases = (MaterialRelease.where(project: accessible_projects)) @material_releases = (MaterialRelease.where(project: accessible_projects))
@medical_releases = MedicalRelease.where(project: accessible_projects)
@misc_releases = MiscRelease.where(project: accessible_projects)
@talent_releases = (TalentRelease.where(project: accessible_projects)) @talent_releases = (TalentRelease.where(project: accessible_projects))
@notes = notes_query(Note.where(notable: @appearance_releases + @location_releases + @material_releases + @talent_releases + @acquired_media_releases )) @notes = notes_query(Note.where(notable: @appearance_releases + @location_releases + @material_releases + @medical_releases + @misc_releases + @talent_releases + @acquired_media_releases ))
render json: { render json: {
data: { data: {
@@ -22,6 +24,8 @@ class Api::SyncController < Api::ApiController
appearance_releases: releases_query(@appearance_releases), appearance_releases: releases_query(@appearance_releases),
location_releases: releases_query(@location_releases), location_releases: releases_query(@location_releases),
material_releases: releases_query(@material_releases), material_releases: releases_query(@material_releases),
medical_releases: releases_query(@medical_releases),
misc_releases: releases_query(@misc_releases),
talent_releases: releases_query(@talent_releases), talent_releases: releases_query(@talent_releases),
notes: @notes notes: @notes
} }

View File

@@ -17,5 +17,11 @@ class Api::TalentReleasesController < Api::ReleasesController
guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io])) guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io]))
release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename]) release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename])
end end
guardian_2_photo = release_create_params[:guardian_2_photo]
if guardian_2_photo
guardian_2_photo[:io] = StringIO.new(Base64.decode64(guardian_2_photo[:io]))
release.guardian_2_photo.attach(io: guardian_2_photo[:io], filename: guardian_2_photo[:filename])
end
end end
end end

View File

@@ -1,14 +1,24 @@
# frozen_string_literal: true
require './lib/knock_monkeypatch'
class Api::UserTokenController < Knock::AuthTokenController class Api::UserTokenController < Knock::AuthTokenController
include Oath::ControllerHelpers
include RememberMe::Controller
skip_before_action :verify_authenticity_token skip_before_action :verify_authenticity_token
before_action :sign_in_user
rescue_from Exception, :with => :return_error rescue_from Exception, :with => :return_error
# Catch exception and return JSON-formatted error # Catch exception and return JSON-formatted error
def return_error(exception) def return_error(exception)
Raven.capture_exception(exception)
logger.error "==Handled=======" logger.error "==Handled======="
logger.error exception.message logger.error exception.message
logger.error exception.backtrace.join("\n") logger.error exception.backtrace.join("\n")
logger.error "==Handled=======" logger.error "==Handled======="
case exception case exception
when ActiveRecord::RecordNotFound when ActiveRecord::RecordNotFound
@status = 404 @status = 404
@@ -25,12 +35,18 @@ class Api::UserTokenController < Knock::AuthTokenController
end end
# for some reason render json_errors is not working # for some reason render json_errors is not working
# simulating JSON API support # simulating JSON API support
render json: { render json: {
errors: [{ errors: [{
status: @status.to_s, status: @status.to_s,
title: @message title: @message
}] }]
} }
end end
private
def sign_in_user
sign_in(entity)
end
end end

View File

@@ -0,0 +1,33 @@
# frozen_string_literal: true
class Api::UsersController < Api::ApiController
skip_before_action :authenticate_user
before_action :verify_custom_token, only: :create
def create
if user_params[:email].nil? || user_params[:password].nil?
raise ActionController::ParameterMissing.new 'Missing email or password'
end
user = Oath::Services::SignUp.new(user_params).perform
render json: user.slice(:email, :created_at, :first_name, :last_name)
end
private
def user_params
params.require(:user).permit(%i[
email
password
first_name
last_name
])
end
def verify_custom_token
if token.blank? || token != ENV['CUSTOM_API_TOKEN']
unauthorized_entity(:user)
end
end
end

View File

@@ -3,7 +3,6 @@
class AppearanceReleaseImportsController < ApplicationController class AppearanceReleaseImportsController < ApplicationController
include AppearanceReleaseContext include AppearanceReleaseContext
include ProjectContext include ProjectContext
include CreateReleasableJobs
before_action :set_project, only: [:create] before_action :set_project, only: [:create]
@@ -11,24 +10,16 @@ class AppearanceReleaseImportsController < ApplicationController
def create def create
authorize AppearanceRelease authorize AppearanceRelease
@failed_files = []
attachments = appearance_release_params attachments = appearance_release_params
if attachments.nil? if attachments.nil?
alert_message = t 'appearance_releases.create.no_attachments' alert_message = t 'appearance_releases.create.no_attachments'
redirect_to [@project, :appearance_releases], alert: alert_message
else else
attachments.each do |attachment| MatchAppearanceReleasesJob.perform_later(@project, attachments)
create_imported_appearance_release attachment notice_message = t 'appearance_releases.create.matching_started'
end redirect_to [@project, :appearance_releases], notice: notice_message
end end
unless @failed_files.empty?
alert_message = t 'appearance_releases.create.failed_import'
alert_message += '<br><ul>'
@failed_files.each { |file_name| alert_message += "<li>#{file_name}</li>" }
alert_message += '</ul>'
end
redirect_to [@project, :appearance_releases], alert: alert_message
end end
private private
@@ -45,45 +36,7 @@ class AppearanceReleaseImportsController < ApplicationController
params.require(:attachments) params.require(:attachments)
end end
def build_appearance_release(params = {}) def acceptable_extensions
authorize appearance_releases.build(params) AppearanceRelease.acceptable_import_file_extensions
end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_non_native_release, release_type: AppearanceRelease.to_s, user_agent: request.user_agent, user_ip: request.remote_ip)
end
def create_imported_appearance_release(attachment)
blob = ActiveStorage::Blob.find_signed(attachment)
return if blob.nil?
extension = blob.filename.extension_with_delimiter
unless AppearanceRelease.acceptable_import_file_extensions.include? extension
blob.purge
@failed_files << blob.filename
return
end
random_contract_no = AppearanceRelease.random_contract_number.to_s
appearance_release_params = {
person_last_name: random_contract_no
}
if blob.image?
appearance_release_params[:person_photo] = attachment
appearance_release_params[:person_first_name] = I18n.t('appearance_releases.shared.imported_appearance_release_headshot_name')
elsif extension == '.pdf'
appearance_release_params[:contract] = attachment
appearance_release_params[:person_first_name] = I18n.t('appearance_releases.shared.imported_appearance_release_contract_name')
end
appearance_release = build_appearance_release(appearance_release_params)
if appearance_release.save(context: :non_native)
log_create_analytics
after_create appearance_release
else
@failed_files << blob.filename
end
end end
end end

View File

@@ -18,7 +18,6 @@ class AppearanceReleasesController < ApplicationController
@appearance_release = build_appearance_release(appearance_release_params) @appearance_release = build_appearance_release(appearance_release_params)
if @appearance_release.save(context: :non_native) if @appearance_release.save(context: :non_native)
log_create_analytics
AddHeadshotCollectionUidToProjectJob.perform_later(@project) AddHeadshotCollectionUidToProjectJob.perform_later(@project)
SetTagsForReleasableJob.perform_later(@appearance_release) SetTagsForReleasableJob.perform_later(@appearance_release)
redirect_to [@project, :appearance_releases], notice: "The release has been imported. #{link_to_import_another}" redirect_to [@project, :appearance_releases], notice: "The release has been imported. #{link_to_import_another}"
@@ -77,9 +76,43 @@ class AppearanceReleasesController < ApplicationController
results results
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_email
person_photo
person_address_street1
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
]
end
def appearance_release_params def appearance_release_params
params.require(:appearance_release).permit(:contract, :guardian_address, :guardian_first_name, :guardian_last_name, :guardian_phone, :guardian_photo, :minor, params.require(:appearance_release).permit(person_params,
:person_address, :person_first_name, :person_last_name, :person_phone, :person_email, :person_photo, guardian_params, second_guardian_params,
:contract, :minor,
:applicable_medium_id, :applicable_medium_text, :applicable_medium_id, :applicable_medium_text,
:territory_id, :territory_text, :territory_id, :territory_text,
:term_id, :term_text, :person_date_of_birth, :term_id, :term_text, :person_date_of_birth,
@@ -93,8 +126,4 @@ class AppearanceReleasesController < ApplicationController
def link_to_import_another def link_to_import_another
view_context.link_to "Import Another", [:new, @project, :appearance_release] view_context.link_to "Import Another", [:new, @project, :appearance_release]
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_non_native_release, release_type: AppearanceRelease.to_s, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -0,0 +1,48 @@
class ApprovalsController < ApplicationController
before_action :set_releasable
before_action :set_project
layout "project"
def create
@releasable.approve_by(current_user)
@releasable.approved_by_user_signature.attach(approved_by_user_signature_params) if signature_data.present?
if @releasable.save(context: :approval)
redirect_to [@project, "#{@releasable_param.name.pluralize}"], notice: t('.release_approved', release_type: @releasable.model_name.human)
else
render :new
end
end
private
def releasable_param
@releasable_param ||= ReleasableParam.new(params.to_unsafe_h)
end
def set_releasable
@releasable = authorize policy_scope(releasable_param.type).find(releasable_param.id)
end
def set_project
@project = @releasable.project
end
def releasable_params
params.require(releasable_param.name).permit(approved_by_user_signature: :data)
end
def signature_data
releasable_params.dig(:approved_by_user_signature, :data)
end
def approved_by_user_signature_params
{
data: signature_data,
filename: "approved_by_user_signature.png",
content_type: "image/png",
identify: false,
}
end
end

View File

@@ -0,0 +1,26 @@
class BroadcastRecordingsController < ApplicationController
layout "project"
before_action :set_project
before_action :set_broadcast
before_action :set_recording
def destroy
@recording.update(hidden: true)
@recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
end
private
def set_project
@project = policy_scope(Project).find(params[:project_id])
end
def set_broadcast
@broadcast = authorize policy_scope(@project.broadcasts).find(params[:broadcast_id])
end
def set_recording
@recording = authorize policy_scope(@broadcast.broadcast_recordings).find(params[:id])
end
end

View File

@@ -1,10 +1,11 @@
class BroadcastsController < ApplicationController class BroadcastsController < ApplicationController
layout "project" layout "project"
before_action :set_project before_action :set_project
before_action :build_broadcast, only: [:new, :create] before_action :build_broadcast, only: [:new, :create]
before_action :set_broadcast, only: [:show, :destroy, :update] before_action :set_broadcast, only: [:show, :destroy, :update, :destroy_file]
before_action :set_multi_view_broadcasts, only: [:show] before_action :set_multi_view_broadcasts, only: [:show]
before_action :show_splash_screen, only: :index
def index def index
@broadcasts = filtered_broadcasts.order_by_recent.paginate(page: params[:page]) @broadcasts = filtered_broadcasts.order_by_recent.paginate(page: params[:page])
@@ -22,23 +23,28 @@ class BroadcastsController < ApplicationController
else else
render :new render :new
end end
end rescue MuxRuby::ApiError, ActiveResource::ConnectionError => e
Raven.capture_exception(e)
def update redirect_to [@project, :broadcasts], alert: t(".alert")
@broadcast.update(broadcast_params)
@files = @broadcast.files.order("created_at DESC").paginate(page: 1)
pagination_content = ApplicationController.render html: helpers.will_paginate(@files, params: { active_tab: params[:active_tab] })
BroadcastsChannel.file_upload_updates(@broadcast, @files, pagination_content)
end end
def show def show
@conference_url = url_for [@broadcast.project, @broadcast, :zoom_meeting] @conference_url = conference_url_for(@broadcast)
@recordings = @broadcast.broadcast_recordings.order_by_recent.paginate(page: params[:page]) @recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
@files = @broadcast.files.order("created_at DESC").paginate(page: params[:page]) @files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page])
render layout: 'application' render layout: 'application'
end end
def update
unless params.has_key?(:broadcast)
@broadcast.regenerate_token
redirect_to([@project, @broadcast], notice: t('.reset_notice')) and return
end
@broadcast.update(broadcast_params)
update_files_section
end
def destroy def destroy
if @broadcast.destroy if @broadcast.destroy
redirect_to [@project, :broadcasts], alert: t(".alert") redirect_to [@project, :broadcasts], alert: t(".alert")
@@ -47,10 +53,29 @@ class BroadcastsController < ApplicationController
end end
end end
def destroy_file
authorize Broadcast
file = ActiveStorage::Attachment.find(params[:file_id])
file.destroy
update_files_section
end
private private
def update_files_section
@files = @broadcast.files.order("created_at DESC").paginate(page: 1)
pagination_content = ApplicationController.render html: helpers.will_paginate(@files, params: { active_tab: params[:active_tab], page: params[:page], active_files_tab: params[:active_files_tab] })
BroadcastsChannel.broadcast_file_upload_updates(@broadcast, @files, pagination_content)
end
def show_splash_screen
render :splash if broadcasts.count.zero?
end
def broadcast_params def broadcast_params
params.require(:broadcast).permit(:name, files: []) params.require(:broadcast).permit(:name, :shoot_location_time_zone, files: [])
end end
def set_project def set_project
@@ -71,7 +96,10 @@ class BroadcastsController < ApplicationController
def set_multi_view_broadcasts def set_multi_view_broadcasts
authorized_broadcasts = authorize policy_scope(Broadcast).where(id: params[:multi_view_ids]).order_by_recent authorized_broadcasts = authorize policy_scope(Broadcast).where(id: params[:multi_view_ids]).order_by_recent
@multi_view_broadcasts = authorized_broadcasts.map { |b| MultiViewBroadcast.new(b, params[:multi_view_ids]) } @multi_view_broadcasts = authorized_broadcasts.map do |b|
files_page = params[:files_page] if params[:active_files_tab] == b.token
MultiViewBroadcast.new(b, params[:multi_view_ids], files_page)
end
end end
def filtered_broadcasts def filtered_broadcasts
@@ -84,26 +112,39 @@ class BroadcastsController < ApplicationController
results results
end end
def conference_url_for(broadcast)
broadcast.video_conference_url_override || url_for([broadcast.project, broadcast, :zoom_meeting])
end
def log_create_analytics def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_live_stream, user_agent: request.user_agent, user_ip: request.remote_ip) TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_live_stream, user_agent: request.user_agent, user_ip: request.remote_ip)
end end
class MultiViewBroadcast class MultiViewBroadcast
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
delegate_missing_to :@broadcast delegate_missing_to :@broadcast
def initialize(broadcast, multi_view_ids) def initialize(broadcast, multi_view_ids, paginate_page)
@broadcast = broadcast @broadcast = broadcast
@multi_view_ids = multi_view_ids @multi_view_ids = multi_view_ids
@paginate_page = paginate_page
end end
def url def url
project_broadcast_path(@broadcast.project, @broadcast, multi_view_ids: @multi_view_ids, locale: I18n.locale) project_broadcast_path(@broadcast.project, @broadcast, multi_view_ids: @multi_view_ids, locale: I18n.locale)
end end
def files
@broadcast.files.order("created_at DESC").paginate(page: @paginate_page)
end
def uid def uid
id id
end end
def self.model_name
Broadcast.model_name
end
end end
end end

View File

@@ -0,0 +1,13 @@
module MedicalReleaseContext
extend ActiveSupport::Concern
def medical_releases
policy_scope(MedicalRelease)
end
def set_medical_release
medical_release_id = params[:medical_release_id] || params[:id]
@medical_release = authorize medical_releases.find(medical_release_id)
end
end

View File

@@ -0,0 +1,13 @@
module MiscReleaseContext
extend ActiveSupport::Concern
def misc_releases
policy_scope(MiscRelease)
end
def set_misc_release
misc_release_id = params[:misc_release_id] || params[:id]
@misc_release = authorize misc_releases.find(misc_release_id)
end
end

View File

@@ -0,0 +1,33 @@
# frozen_string_literal: true
class ContractTemplates::DuplicatesController < ApplicationController
before_action :set_contract_template
def create
authorize(ContractTemplate)
new_contract_template = @contract_template.dup
new_contract_template.name = I18n.t('contract_templates.duplicate.name_prefix', template_name: @contract_template.name)
# Duplicate rich text fields
new_contract_template.body = @contract_template.body
new_contract_template.guardian_clause = @contract_template.guardian_clause
new_contract_template.signature_legal_text = @contract_template.signature_legal_text
if new_contract_template.save
redirect_to [:edit, new_contract_template]
else
redirect_to [@contract_template.project, :contract_templates], alert: t('.error')
end
end
private
def contract_templates
policy_scope(ContractTemplate)
end
def set_contract_template
@contract_template = contract_templates.find(params[:contract_template_id])
end
end

View File

@@ -16,7 +16,12 @@ class ContractTemplates::QrCodesController < ApplicationController
end end
def qr_code def qr_code
authorize QrCode.build_from_contract_template(@contract_template) if params[:multi_sign_ids].present?
contract_templates_group = authorize contract_templates.where(id: params[:multi_sign_ids]).order_by_recent
authorize QrCode.build_from_multiple_contract_templates(contract_templates_group, @contract_template.project)
else
authorize QrCode.build_from_contract_template(@contract_template)
end
end end
def download_attributes def download_attributes

View File

@@ -5,8 +5,10 @@ class ContractTemplatesController < ApplicationController
layout 'project' layout 'project'
before_action :set_project, except: [:destroy] before_action :set_project, except: [:destroy, :edit, :update]
before_action :set_contract_template, only: [:destroy] before_action :set_contract_template, only: [:destroy, :edit, :update]
before_action :set_project_from_contract_template, only: [:edit, :update]
before_action :show_splash_screen, only: :index
def index def index
@contract_templates = contract_templates.non_archived.order_by_name.paginate(page: params[:page]) @contract_templates = contract_templates.non_archived.order_by_name.paginate(page: params[:page])
@@ -24,6 +26,7 @@ class ContractTemplatesController < ApplicationController
contract = Contract.new releasable_instance, true contract = Contract.new releasable_instance, true
send_file contract.to_pdf, download_attributes send_file contract.to_pdf, download_attributes
elsif @contract_template.save elsif @contract_template.save
log_create_analytics
redirect_to [@project, :contract_templates], notice: t('.notice') redirect_to [@project, :contract_templates], notice: t('.notice')
else else
@release_type = contract_template_params[:release_type] @release_type = contract_template_params[:release_type]
@@ -31,6 +34,20 @@ class ContractTemplatesController < ApplicationController
end end
end end
def edit
@release_type = @contract_template.release_type
end
def update
@contract_template.attributes = contract_template_params
if @contract_template.save
redirect_to [@project, :contract_templates], notice: t('.notice')
else
render :edit
end
end
def destroy def destroy
@contract_template.archive @contract_template.archive
redirect_to [@contract_template.project, :contract_templates], alert: t('.archived_notice') redirect_to [@contract_template.project, :contract_templates], alert: t('.archived_notice')
@@ -38,6 +55,14 @@ class ContractTemplatesController < ApplicationController
private private
def set_project_from_contract_template
@project = @contract_template.project
end
def show_splash_screen
render :splash if contract_templates.non_archived.count.zero?
end
def set_contract_template def set_contract_template
@contract_template = authorize contract_templates.find(params[:id]) @contract_template = authorize contract_templates.find(params[:id])
end end
@@ -57,11 +82,22 @@ class ContractTemplatesController < ApplicationController
def contract_template_params def contract_template_params
params params
.require(:contract_template) .require(:contract_template)
.permit(:name, :release_type, :body, :guardian_clause, :fee, .permit(:name, :release_type, :body, :guardian_clause,
:signature_legal_text, :fee, :amendment_clause,
:applicable_medium_id, :applicable_medium_text, :applicable_medium_id, :applicable_medium_text,
:territory_id, :territory_text, :territory_id, :territory_text,
:term_id, :term_text, :term_id, :term_text, :accessibility,
:restriction_id, :restriction_text) :restriction_id, :restriction_text,
:question_1_text, :question_2_text,
:question_3_text, :question_4_text,
:question_5_text, :question_6_text,
:question_7_text, :question_8_text,
:question_9_text, :question_10_text,
:question_11_text, :question_12_text,
:question_13_text, :question_14_text,
:question_15_text, :questionnaire_legal_text,
:exhibit_a_legal_text, :exhibit_a_question_text,
:exhibit_b_legal_text, :exhibit_b_question_text)
end end
def download_attributes def download_attributes
@@ -71,4 +107,8 @@ class ContractTemplatesController < ApplicationController
type: 'application/pdf' type: 'application/pdf'
} }
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_contract_template, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -48,8 +48,10 @@ class ContractsController < ApplicationController
# Native release contracts must be generated on-the-fly; non-native releases have a contract attachment # Native release contracts must be generated on-the-fly; non-native releases have a contract attachment
if releasable.native? if releasable.native?
send_file contract.to_pdf, download_attributes send_file contract.to_pdf, download_attributes
else elsif policy(contract).show?
redirect_to releasable.contract.service_url redirect_to releasable.contract.service_url
else
raise Pundit::NotAuthorizedError
end end
end end
end end

View File

@@ -1,4 +1,4 @@
class FileInfosController < ApplicationController class FilesController < ApplicationController
before_action :set_releasable before_action :set_releasable
layout "project" layout "project"
@@ -16,7 +16,7 @@ class FileInfosController < ApplicationController
if @releasable.update(releasable_params) if @releasable.update(releasable_params)
SetTagsForReleasableJob.perform_later(@releasable) SetTagsForReleasableJob.perform_later(@releasable)
redirect_to [@project, @releasable.model_name.plural], notice: t(".notice") redirect_to [@project, @releasable.model_name.plural], notice: "Files added successfully to the release."
else else
render :edit render :edit
end end
@@ -29,16 +29,10 @@ class FileInfosController < ApplicationController
end end
def set_releasable def set_releasable
@releasable = authorize policy_scope(releasable_param.type).find(releasable_param.id), :"#{action_name}_file_infos?" @releasable = authorize policy_scope(releasable_param.type).find(releasable_param.id), :edit_files?
end end
def releasable_params def releasable_params
params.fetch(releasable_param.name, {}).permit( params.fetch(releasable_param.name, {}).permit(files: [])
file_infos_attributes: [
:filename,
:content_type,
:byte_size
],
)
end end
end end

View File

@@ -18,7 +18,6 @@ class LocationReleasesController < ApplicationController
@location_release = build_location_release(location_release_params) @location_release = build_location_release(location_release_params)
if @location_release.save if @location_release.save
log_create_analytics
SetTagsForReleasableJob.perform_later(@location_release) SetTagsForReleasableJob.perform_later(@location_release)
redirect_to [@project, :location_releases], notice: t(".notice") redirect_to [@project, :location_releases], notice: t(".notice")
else else
@@ -68,7 +67,8 @@ class LocationReleasesController < ApplicationController
:territory_id, :territory_text, :territory_id, :territory_text,
:term_id, :term_text, :term_id, :term_text,
:restriction_id, :restriction_text, :restriction_id, :restriction_text,
:filming_started_on, :filming_ended_on :filming_started_on, :filming_ended_on,
:filming_hours
) )
end end
@@ -89,8 +89,4 @@ class LocationReleasesController < ApplicationController
results results
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_non_native_release, release_type: LocationRelease.to_s, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -18,7 +18,6 @@ class MaterialReleasesController < ApplicationController
@material_release = build_material_release(material_release_params) @material_release = build_material_release(material_release_params)
if @material_release.save if @material_release.save
log_create_analytics
SetTagsForReleasableJob.perform_later(@material_release) SetTagsForReleasableJob.perform_later(@material_release)
redirect_to [@project, :material_releases], notice: t(".notice") redirect_to [@project, :material_releases], notice: t(".notice")
else else
@@ -50,11 +49,58 @@ class MaterialReleasesController < ApplicationController
private private
def person_params
%i[
person_first_name
person_last_name
person_phone
person_company
person_email
person_title
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def material_release_params def material_release_params
params.require(:material_release).permit( params.require(:material_release).permit(person_params, guardian_params, second_guardian_params, :minor,
:name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country, :name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country,
:person_first_name, :person_last_name, :person_title, :person_company, :person_phone, :person_email,
:person_address_street1, :person_address_street2, :person_address_city, :person_address_state, :person_address_zip, :person_address_country,
:applicable_medium_id, :applicable_medium_text, :applicable_medium_id, :applicable_medium_text,
:territory_id, :territory_text, :territory_id, :territory_text,
:term_id, :term_text, :term_id, :term_text,
@@ -89,8 +135,4 @@ class MaterialReleasesController < ApplicationController
results results
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_non_native_release, release_type: MaterialRelease.to_s, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -0,0 +1,40 @@
class MedicalReleasesController < ApplicationController
include ProjectContext, MedicalReleaseContext
before_action :set_project, only: [:index]
before_action :set_medical_release, only: [:destroy]
include ProjectLayout
def index
@medical_releases = filtered_medical_releases.order_by_recent.paginate(page: params[:page])
end
def destroy
@project = @medical_release.project
if @medical_release.destroy
redirect_to [@project, :medical_releases], alert: t(".alert")
end
end
private
def medical_releases
if @project
policy_scope(@project.medical_releases)
else
policy_scope(MedicalRelease)
end
end
def filtered_medical_releases
results = medical_releases
if params[:query].present?
results = results.search(params[:query])
end
results
end
end

View File

@@ -0,0 +1,40 @@
class MiscReleasesController < ApplicationController
include ProjectContext, MiscReleaseContext
before_action :set_project, only: [:index]
before_action :set_misc_release, only: [:destroy]
include ProjectLayout
def index
@misc_releases = filtered_misc_releases.order_by_recent.paginate(page: params[:page])
end
def destroy
@project = @misc_release.project
if @misc_release.destroy
redirect_to [@project, :misc_releases], alert: t(".alert")
end
end
private
def misc_releases
if @project
policy_scope(@project.misc_releases)
else
policy_scope(MiscRelease)
end
end
def filtered_misc_releases
results = misc_releases
if params[:query].present?
results = results.search(params[:query])
end
results
end
end

View File

@@ -22,7 +22,6 @@ class MusicReleasesController < ApplicationController
@music_release = build_music_release(music_release_params) @music_release = build_music_release(music_release_params)
if @music_release.save if @music_release.save
log_create_analytics
SetTagsForReleasableJob.perform_later(@music_release) SetTagsForReleasableJob.perform_later(@music_release)
redirect_to [@project, :music_releases], notice: t(".notice") redirect_to [@project, :music_releases], notice: t(".notice")
else else
@@ -111,8 +110,4 @@ class MusicReleasesController < ApplicationController
results results
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_non_native_release, release_type: MusicRelease.to_s, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -6,7 +6,7 @@ class ProjectsController < ApplicationController
before_action :set_project, only: [:show, :edit, :update, :destroy] before_action :set_project, only: [:show, :edit, :update, :destroy]
def index def index
@projects = policy_scope(Current.account.projects).order_by_name @projects = filtered_projects.order_by_name
end end
def new def new
@@ -46,6 +46,20 @@ class ProjectsController < ApplicationController
private private
def filtered_projects
results = projects
if params[:query].present?
results = results.search(params[:query])
end
results
end
def projects
authorize policy_scope(Current.account.projects)
end
def set_project def set_project
@project = authorize projects.find(params[:id]) @project = authorize projects.find(params[:id])
end end
@@ -60,7 +74,7 @@ class ProjectsController < ApplicationController
end end
def features_settings_params def features_settings_params
%i(appearance_release location_release material_release acquired_media_release music_release talent_release video_analysis) %i(appearance_release location_release material_release acquired_media_release music_release talent_release medical_release misc_release video_analysis)
end end
def project_params_with_current_account def project_params_with_current_account

View File

@@ -10,7 +10,6 @@ class Public::AcquiredMediaReleasesController < Public::BaseController
@acquired_media_release = build_acquired_media_release(acquired_media_release_params_with_locale_and_contract_template) @acquired_media_release = build_acquired_media_release(acquired_media_release_params_with_locale_and_contract_template)
if @acquired_media_release.save(context: :native) if @acquired_media_release.save(context: :native)
log_create_analytics
after_create(@acquired_media_release) after_create(@acquired_media_release)
else else
render :new render :new
@@ -41,28 +40,67 @@ class Public::AcquiredMediaReleasesController < Public::BaseController
end end
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_fax
person_email
person_title
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def acquired_media_release_params def acquired_media_release_params
params.require(:acquired_media_release).permit( params.require(:acquired_media_release).permit(person_params,
:name, guardian_params,
:description, second_guardian_params,
:person_title, :minor,
:person_phone, :name,
:person_fax, :description,
:person_address_street1, :signature_base64,
:person_address_street2, :locale, :contract_template,
:person_address_city, categories: [],
:person_address_state, files: []
:person_address_zip, )
:person_address_country,
:signature_base64,
:locale, :contract_template,
categories: [],
file_infos_attributes: [
:filename,
:content_type,
:byte_size
]
)
end end
def acquired_media_release_params_with_locale def acquired_media_release_params_with_locale
@@ -72,8 +110,4 @@ class Public::AcquiredMediaReleasesController < Public::BaseController
def acquired_media_release_params_with_locale_and_contract_template def acquired_media_release_params_with_locale_and_contract_template
acquired_media_release_params_with_locale.merge(contract_template: @contract_template) acquired_media_release_params_with_locale.merge(contract_template: @contract_template)
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(nil, nil, :track_create_native_release, release_type: AcquiredMediaRelease.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -0,0 +1,47 @@
class Public::AmendmentsController < Public::BaseController
skip_after_action :verify_authorized, :verify_policy_scoped
before_action :set_account, :set_project, :set_contract_template, :set_release
def new
if @release.amendment_signed?
render :create, locals: { already_signed: true }
end
end
def create
if @release.amendment_signed?
render :create, locals: { already_signed: true }
return
end
@release.attributes = amendment_params
render :new unless @release.save(context: :amendment)
end
private
def amendment_params
params.require(releasable_param.name).permit(:amendment_signer_name, :amendment_signature_base64)
end
def releasable_param
@releasable_param ||= ReleasableParam.new(params.to_unsafe_h)
end
def set_release
@release = @contract_template.releases.find(releasable_param.id)
end
def set_contract_template
@contract_template = @project.contract_templates.find(params[:contract_template_id])
end
def set_project
@project = @account.projects.find(params[:project_id])
end
def set_account
@account = Account.find_by(slug: params[:account_id])
end
end

View File

@@ -10,7 +10,6 @@ class Public::AppearanceReleasesController < Public::BaseController
@appearance_release = build_appearance_release(appearance_release_params_with_locale_and_contract_template) @appearance_release = build_appearance_release(appearance_release_params_with_locale_and_contract_template)
if @appearance_release.save(context: :native) if @appearance_release.save(context: :native)
log_create_analytics
after_create(@appearance_release) after_create(@appearance_release)
else else
render :new render :new
@@ -39,11 +38,83 @@ class Public::AppearanceReleasesController < Public::BaseController
authorize appearance_releases.build(params) authorize appearance_releases.build(params)
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_email
person_photo
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def questionnaire_params
[
:question_1_answer,
:question_2_answer,
:question_3_answer,
:question_4_answer,
:question_5_answer,
:question_6_answer,
:question_7_answer,
:question_8_answer,
:question_9_answer,
:question_10_answer,
:question_11_answer,
:question_12_answer,
:question_13_answer,
:question_14_answer,
:question_15_answer,
]
end
def appearance_release_params def appearance_release_params
params.require(:appearance_release).permit(:person_address, :person_first_name, :person_last_name, :person_phone, :person_email, :person_photo, params.require(:appearance_release).permit(person_params, guardian_params,
:guardian_address, :guardian_first_name, :guardian_last_name, :guardian_phone, :guardian_photo, :minor, second_guardian_params,
:signature_base64, :person_date_of_birth, questionnaire_params,
:locale, :contract_template,) :minor, :signature_base64,
:person_date_of_birth,
:locale, :contract_template,
:exhibit_a_answer, :exhibit_b_answer
)
end end
def appearance_release_params_with_locale def appearance_release_params_with_locale
@@ -53,8 +124,4 @@ class Public::AppearanceReleasesController < Public::BaseController
def appearance_release_params_with_locale_and_contract_template def appearance_release_params_with_locale_and_contract_template
appearance_release_params_with_locale.merge(contract_template: @contract_template) appearance_release_params_with_locale.merge(contract_template: @contract_template)
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(nil, nil, :track_create_native_release, release_type: AppearanceRelease.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -3,11 +3,11 @@ class Public::BroadcastsController < Public::BaseController
before_action :set_broadcast, only: [:show, :update] before_action :set_broadcast, only: [:show, :update]
def show def show
@conference_url = broadcast_zoom_meeting_url(@broadcast.token) @conference_url = conference_url_for(@broadcast)
@multi_view_broadcasts = multi_view_broadcasts @multi_view_broadcasts = multi_view_broadcasts
@recordings = @broadcast.broadcast_recordings.order_by_recent.paginate(page: params[:page]) @recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
@files = @broadcast.files.order("created_at DESC").paginate(page: params[:page]) @files = @broadcast.files.order("created_at DESC").paginate(page: params[:files_page])
render 'broadcasts/show' render 'broadcasts/show'
end end
@@ -15,8 +15,8 @@ class Public::BroadcastsController < Public::BaseController
@broadcast.update(broadcast_params) @broadcast.update(broadcast_params)
@files = @broadcast.files.order("created_at DESC").paginate(page: 1) @files = @broadcast.files.order("created_at DESC").paginate(page: 1)
pagination_content = ApplicationController.render html: helpers.will_paginate(@files, params: { active_tab: params[:active_tab] }) pagination_content = ApplicationController.render html: helpers.will_paginate(@files,params: { active_tab: params[:active_tab], page: params[:page], active_files_tab: params[:active_files_tab] })
BroadcastsChannel.file_upload_updates(@broadcast, @files, pagination_content) BroadcastsChannel.broadcast_file_upload_updates(@broadcast, @files, pagination_content)
end end
private private
@@ -29,29 +29,49 @@ class Public::BroadcastsController < Public::BaseController
Broadcast. Broadcast.
where(token: params[:multi_view_tokens]). where(token: params[:multi_view_tokens]).
order_by_recent. order_by_recent.
map { |b| MultiViewBroadcast.new(b, params[:multi_view_tokens]) } map do |b|
files_page = params[:files_page] if params[:active_files_tab] == b.token
MultiViewBroadcast.new(b, params[:multi_view_tokens], files_page)
end
end end
def set_broadcast def set_broadcast
@broadcast = Broadcast.find_by_token(params[:token]) @broadcast = Broadcast.find_by_token(params[:token])
unless @broadcast.present?
redirect_to [:new, :session], alert: t(".alert")
end
end
def conference_url_for(broadcast)
broadcast.video_conference_url_override || broadcast_zoom_meeting_url(broadcast.token)
end end
class MultiViewBroadcast class MultiViewBroadcast
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
delegate_missing_to :@broadcast delegate_missing_to :@broadcast
def initialize(broadcast, multi_view_tokens) def initialize(broadcast, multi_view_tokens, paginate_page)
@broadcast = broadcast @broadcast = broadcast
@multi_view_tokens = multi_view_tokens @multi_view_tokens = multi_view_tokens
@paginate_page = paginate_page
end end
def url def url
broadcast_url(uid, multi_view_tokens: @multi_view_tokens, host: AppHost.new.domain_with_port, locale: I18n.locale) broadcast_url(uid, multi_view_tokens: @multi_view_tokens, host: AppHost.new.domain_with_port, locale: I18n.locale)
end end
def files
@broadcast.files.order("created_at DESC").paginate(page: @paginate_page)
end
def uid def uid
token token
end end
def self.model_name
Broadcast.model_name
end
end end
end end

View File

@@ -0,0 +1,18 @@
class Public::ContractTemplatesController < Public::BaseController
skip_after_action :verify_authorized, :verify_policy_scoped
before_action :set_account, :set_project
def index
@contract_templates = @project.contract_templates.where(id: params[:contract_template_ids]).order_by_name.paginate(page: params[:page])
end
private
def set_project
@project = @account.projects.find(params[:project_id])
end
def set_account
@account = Account.find_by(slug: params[:account_id])
end
end

View File

@@ -10,7 +10,6 @@ class Public::LocationReleasesController < Public::BaseController
@location_release = build_location_release(location_release_params_with_locale_and_contract_template) @location_release = build_location_release(location_release_params_with_locale_and_contract_template)
if @location_release.save(context: :native) if @location_release.save(context: :native)
log_create_analytics
after_create(@location_release) after_create(@location_release)
else else
render :new render :new
@@ -63,7 +62,9 @@ class Public::LocationReleasesController < Public::BaseController
:person_address_zip, :person_address_zip,
:person_address_country, :person_address_country,
:signature_base64, :signature_base64,
:locale, :contract_template, :filming_started_on, :filming_ended_on :locale, :contract_template, :filming_started_on, :filming_ended_on,
:filming_hours,
photos: []
) )
end end
@@ -74,8 +75,4 @@ class Public::LocationReleasesController < Public::BaseController
def location_release_params_with_locale_and_contract_template def location_release_params_with_locale_and_contract_template
location_release_params_with_locale.merge(contract_template: @contract_template) location_release_params_with_locale.merge(contract_template: @contract_template)
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(nil, nil, :track_create_native_release, release_type: LocationRelease.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -10,7 +10,6 @@ class Public::MaterialReleasesController < Public::BaseController
@material_release = build_material_release(material_release_params_with_locale_and_contract_template) @material_release = build_material_release(material_release_params_with_locale_and_contract_template)
if @material_release.save(context: :native) if @material_release.save(context: :native)
log_create_analytics
after_create(@material_release) after_create(@material_release)
else else
render :new render :new
@@ -39,13 +38,61 @@ class Public::MaterialReleasesController < Public::BaseController
authorize material_releases.build(params) authorize material_releases.build(params)
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_email
person_title
person_company
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def material_release_params def material_release_params
params.require(:material_release).permit( params.require(:material_release).permit(person_params, guardian_params, second_guardian_params, :minor,
:name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country, :name, :address_street1, :address_street2, :address_city, :address_state, :address_zip, :address_country,
:person_first_name, :person_last_name, :person_title, :person_company, :person_phone, :person_email,
:person_address_street1, :person_address_street2, :person_address_city, :person_address_state, :person_address_zip, :person_address_country,
:signature_base64, :signature_base64,
:locale, :contract_template, :description :locale, :contract_template, :description, photos: []
) )
end end
@@ -56,8 +103,4 @@ class Public::MaterialReleasesController < Public::BaseController
def material_release_params_with_locale_and_contract_template def material_release_params_with_locale_and_contract_template
material_release_params_with_locale.merge(contract_template: @contract_template) material_release_params_with_locale.merge(contract_template: @contract_template)
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(nil, nil, :track_create_native_release, release_type: MaterialRelease.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -0,0 +1,118 @@
class Public::MedicalReleasesController < Public::BaseController
before_action :set_account, :set_project, :set_contract_template
def new
@medical_release = build_medical_release
end
def create
@medical_release = build_medical_release(medical_release_params_with_locale_and_contract_template)
if @medical_release.save(context: :native)
if @medical_release.contract_template.present?
AttachContractToReleasableJob.perform_later(@medical_release)
end
else
render :new
end
end
private
def set_project
@project = @account.projects.find(params[:project_id])
end
def set_account
@account = Account.find_by(slug: params[:account_id])
end
def set_contract_template
@contract_template = @project.contract_templates.find(params[:contract_template_id])
end
def medical_releases
policy_scope(@project.medical_releases)
end
def build_medical_release(params = {})
authorize medical_releases.build(params)
end
def medical_release_params
params
.require(:medical_release)
.permit(
person_params,
guardian_params,
second_guardian_params,
:minor,
:signature_base64,
:locale,
:contract_template,
:question_1_answer, :question_2_answer,
:question_3_answer, :question_4_answer,
:question_5_answer, :question_6_answer,
:question_7_answer, :question_8_answer,
:question_9_answer, :question_10_answer,
:question_11_answer, :question_12_answer,
:question_13_answer, :question_14_answer,
:question_15_answer, photos: [],
)
end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_email
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
guardian_photo
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_photo
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
]
end
def medical_release_params_with_locale
medical_release_params.merge(locale: I18n.locale)
end
def medical_release_params_with_locale_and_contract_template
medical_release_params_with_locale.merge(contract_template: @contract_template)
end
end

View File

@@ -0,0 +1,123 @@
class Public::MiscReleasesController < Public::BaseController
before_action :set_account, :set_project, :set_contract_template
def new
@misc_release = build_misc_release
end
def create
@misc_release = build_misc_release(misc_release_params_with_locale_and_contract_template)
if @misc_release.save(context: :native)
if @misc_release.contract_template.present?
AttachContractToReleasableJob.perform_later(@misc_release)
end
else
render :new
end
end
private
def set_project
@project = @account.projects.find(params[:project_id])
end
def set_account
@account = Account.find_by(slug: params[:account_id])
end
def set_contract_template
@contract_template = @project.contract_templates.find(params[:contract_template_id])
end
def misc_releases
policy_scope(@project.misc_releases)
end
def build_misc_release(params = {})
authorize misc_releases.build(params)
end
def misc_release_params
params
.require(:misc_release)
.permit(
person_params,
guardian_params,
questionnaire_params,
:signature_base64,
:locale,
:contract_template,
:applicable_medium_id,
:applicable_medium_text,
:territory_id,
:territory_text,
:term_id,
:term_text,
:restriction_id,
:restriction_text,
photos: [],
)
end
def person_params
[
:person_first_name,
:person_last_name,
:person_phone,
:person_email,
:person_address_street1,
:person_address_street2,
:person_address_city,
:person_address_state,
:person_address_zip,
:person_address_country,
]
end
def guardian_params
[
:guardian_first_name,
:guardian_last_name,
:guardian_phone,
:guardian_email,
:minor,
:guardian_address_street1,
:guardian_address_street2,
:guardian_address_city,
:guardian_address_state,
:guardian_address_zip,
:guardian_address_country,
:guardian_photo
]
end
def questionnaire_params
[
:question_1_answer,
:question_2_answer,
:question_3_answer,
:question_4_answer,
:question_5_answer,
:question_6_answer,
:question_7_answer,
:question_8_answer,
:question_9_answer,
:question_10_answer,
:question_11_answer,
:question_12_answer,
:question_13_answer,
:question_14_answer,
:question_15_answer,
]
end
def misc_release_params_with_locale
misc_release_params.merge(locale: I18n.locale)
end
def misc_release_params_with_locale_and_contract_template
misc_release_params_with_locale.merge(contract_template: @contract_template)
end
end

View File

@@ -10,7 +10,6 @@ class Public::TalentReleasesController < Public::BaseController
@talent_release = build_talent_release(talent_release_params_with_locale_and_contract_template) @talent_release = build_talent_release(talent_release_params_with_locale_and_contract_template)
if @talent_release.save(context: :native) if @talent_release.save(context: :native)
log_create_analytics
after_create(@talent_release) after_create(@talent_release)
else else
render :new render :new
@@ -45,42 +44,59 @@ class Public::TalentReleasesController < Public::BaseController
.permit( .permit(
person_params, person_params,
guardian_params, guardian_params,
second_guardian_params,
:signature_base64, :signature_base64,
:locale, :locale,
:contract_template, :contract_template,
photos: [], photos: []
) )
end end
def person_params def person_params
[ %i[
:person_first_name, person_first_name
:person_last_name, person_last_name
:person_phone, person_phone
:person_email, person_email
:person_address_street1, person_address_street1
:person_address_street2, person_address_street2
:person_address_city, person_address_city
:person_address_state, person_address_state
:person_address_zip, person_address_zip
:person_address_country, person_address_country
] ]
end end
def guardian_params def guardian_params
[ %i[
:guardian_first_name, guardian_first_name
:guardian_last_name, guardian_last_name
:guardian_phone, guardian_phone
:guardian_email, guardian_email
:minor, minor
:guardian_address_street1, guardian_address_street1
:guardian_address_street2, guardian_address_street2
:guardian_address_city, guardian_address_city
:guardian_address_state, guardian_address_state
:guardian_address_zip, guardian_address_zip
:guardian_address_country, guardian_address_country
:guardian_photo, guardian_photo
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
guardian_2_photo
] ]
end end
@@ -91,8 +107,4 @@ class Public::TalentReleasesController < Public::BaseController
def talent_release_params_with_locale_and_contract_template def talent_release_params_with_locale_and_contract_template
talent_release_params_with_locale.merge(contract_template: @contract_template) talent_release_params_with_locale.merge(contract_template: @contract_template)
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(nil, nil, :track_create_native_release, release_type: TalentRelease.to_s, account: @account, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -11,7 +11,9 @@ class ReleaseTemplateImportsController < ApplicationController
templates = [] templates = []
filtered_contract_templates.each do |contract_template| filtered_contract_templates.each do |contract_template|
next if contract_template.duplicated? || contract_template.project == @project next if contract_template.duplicated? ||
contract_template.archived? ||
contract_template.project == @project
already_imported = contract_template.duplicates.non_archived.pluck(:project_id).include?(@project.id) already_imported = contract_template.duplicates.non_archived.pluck(:project_id).include?(@project.id)
templates << OpenStruct.new(template: contract_template, already_imported?: already_imported) templates << OpenStruct.new(template: contract_template, already_imported?: already_imported)

View File

@@ -14,6 +14,10 @@ class StreamNotificationsController < ApplicationController
when "video.live_stream.recording" when "video.live_stream.recording"
@broadcast.streamer_recording! @broadcast.streamer_recording!
notify_users notify_users
when "video.asset.ready"
full_live_stream_playback_uid = notification.dig(:data, :playback_ids, 0, :id)
@broadcast.update(full_live_stream_playback_uid: full_live_stream_playback_uid)
notify_users
when "video.live_stream.active" when "video.live_stream.active"
@broadcast.active! @broadcast.active!
notify_users notify_users
@@ -28,9 +32,10 @@ class StreamNotificationsController < ApplicationController
asset_uid = notification.dig(:object, :id) asset_uid = notification.dig(:object, :id)
playback_uid = notification.dig(:data, :playback_ids, 0, :id) playback_uid = notification.dig(:data, :playback_ids, 0, :id)
file_name = notification.dig(:data, :static_renditions, :files, -1, :name) file_name = notification.dig(:data, :static_renditions, :files, -1, :name)
duration = notification.dig(:data, :duration)
recording = @broadcast.broadcast_recordings.create!(asset_uid: asset_uid, asset_playback_uid: playback_uid, file_name: file_name) recording = @broadcast.broadcast_recordings.create!(asset_uid: asset_uid, asset_playback_uid: playback_uid, file_name: file_name, duration: duration)
recordings = @broadcast.broadcast_recordings.order_by_recent.paginate(page: params[:page]) recordings = @broadcast.broadcast_recordings.visible.order_by_recent.paginate(page: params[:page])
link = helpers.link_to(recording.broadcast_name.titleize, recording.download_url, target: "_blank") link = helpers.link_to(recording.broadcast_name.titleize, recording.download_url, target: "_blank")
message = "Your recent live stream has been recorded and is available for download here: #{link}" message = "Your recent live stream has been recorded and is available for download here: #{link}"
@@ -58,11 +63,17 @@ class StreamNotificationsController < ApplicationController
end end
def set_broadcast def set_broadcast
if notification_type == "video.asset.static_renditions.ready" case notification_type
when "video.asset.static_renditions.ready", "video.asset.ready"
live_stream_id = notification.dig(:stream_notification, :data, :live_stream_id) live_stream_id = notification.dig(:stream_notification, :data, :live_stream_id)
@broadcast = Broadcast.find_by!(stream_uid: live_stream_id) @broadcast = Broadcast.find_by(stream_uid: live_stream_id)
else else
@broadcast = Broadcast.find_by!(stream_uid: notification_object_id) @broadcast = Broadcast.find_by(stream_uid: notification_object_id)
end
if @broadcast.nil?
logger.info "Ignoring broadcast from other environment. Type = #{notification_type}. Id = #{live_stream_id} / #{notification_object_id}"
head :ok
end end
end end

View File

@@ -18,7 +18,6 @@ class TalentReleasesController < ApplicationController
@talent_release = build_talent_release(talent_release_params) @talent_release = build_talent_release(talent_release_params)
if @talent_release.save if @talent_release.save
log_create_analytics
AddHeadshotCollectionUidToProjectJob.perform_later(@project) AddHeadshotCollectionUidToProjectJob.perform_later(@project)
SetTagsForReleasableJob.perform_later(@talent_release) SetTagsForReleasableJob.perform_later(@talent_release)
redirect_to [@project, :talent_releases], notice: t(".notice") redirect_to [@project, :talent_releases], notice: t(".notice")
@@ -61,15 +60,67 @@ class TalentReleasesController < ApplicationController
end end
end end
def person_params
%i[
person_first_name
person_last_name
person_phone
person_email
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
]
end
def guardian_params
%i[
guardian_first_name
guardian_last_name
guardian_phone
guardian_email
minor
guardian_address_street1
guardian_address_street2
guardian_address_city
guardian_address_state
guardian_address_zip
guardian_address_country
guardian_photo
]
end
def second_guardian_params
%i[
guardian_2_first_name
guardian_2_last_name
guardian_2_phone
guardian_2_email
guardian_2_address_street1
guardian_2_address_street2
guardian_2_address_city
guardian_2_address_state
guardian_2_address_zip
guardian_2_address_country
guardian_2_photo
]
end
def talent_release_params def talent_release_params
params.require(:talent_release).permit( params.require(:talent_release).permit(person_params,
:person_first_name, :person_last_name, :person_phone, :guardian_photo, :person_email, guardian_params,
:person_address_street1, :person_address_street2, :person_address_city, :person_address_state, :person_address_zip, :person_address_country, second_guardian_params,
:guardian_first_name, :guardian_last_name, :guardian_phone, :guardian_email, :minor, :contract, { photos: [] },
:guardian_address_street1, :guardian_address_street2, :guardian_address_city, :guardian_address_state, :guardian_address_zip, :guardian_address_country, :applicable_medium_id,
:contract, { photos: [] }, :applicable_medium_text,
:applicable_medium_id, :applicable_medium_text, :territory_id, :territory_text, :term_id, :term_text, :restriction_id, :restriction_text :territory_id,
) :territory_text,
:term_id,
:term_text,
:restriction_id,
:restriction_text)
end end
def build_talent_release(attrs = {}) def build_talent_release(attrs = {})
@@ -85,8 +136,4 @@ class TalentReleasesController < ApplicationController
results results
end end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_non_native_release, release_type: TalentRelease.to_s, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end end

View File

@@ -0,0 +1,81 @@
class TaskRequestsController < ApplicationController
layout "project"
before_action :set_project
before_action :build_task_request, only: [:new, :create]
before_action :set_task_request, only: [:show, :edit, :update, :cancel]
before_action :show_splash_screen, only: :index
def index
@task_requests = task_requests.order_by_recent.paginate(page: params[:page])
end
def new
end
def create
@task_request.attributes = task_request_params_with_email
if @task_request.save
log_create_analytics
taskme_url = url_for([:admin, @task_request])
SubmitHubspotTaskRequestFormJob.perform_later(@task_request.user_email, taskme_url)
else
render :new
end
end
def show
@files = @task_request.files.paginate(page: params[:page])
end
def edit
end
def update
if @task_request.update(task_request_params)
redirect_to [@project, :task_requests], notice: t(".notice")
else
render :edit
end
end
def cancel
@task_request.cancelled!
redirect_to [@project, :task_requests], notice: t(".notice")
end
private
def show_splash_screen
render :splash if task_requests.count.zero?
end
def task_request_params
params.require(:task_request).permit(:description, :deadline, :time_allowed, :additional_notes, files: [])
end
def task_request_params_with_email
task_request_params.merge(user_email: Current.user.email)
end
def set_project
@project = policy_scope(Project).find(params[:project_id])
end
def set_task_request
@task_request = authorize policy_scope(TaskRequest).find(params[:id])
end
def task_requests
authorize policy_scope(@project.task_requests)
end
def build_task_request
@task_request = authorize @project.task_requests.build
end
def log_create_analytics
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_task_request, user_agent: request.user_agent, user_ip: request.remote_ip)
end
end

View File

@@ -0,0 +1,19 @@
class TasksController < ApplicationController
before_action :set_project
include ProjectLayout
def index
@tasks = task_requests.completed.order_by_recent.paginate(page: params[:page])
end
private
def set_project
@project = policy_scope(Project).find(params[:project_id])
end
def task_requests
authorize policy_scope(@project.task_requests)
end
end

View File

@@ -3,6 +3,7 @@ class VideosController < ApplicationController
before_action :set_project, only: [:index, :new, :create, :landing] before_action :set_project, only: [:index, :new, :create, :landing]
before_action :set_video, only: [:edit, :update] before_action :set_video, only: [:edit, :update]
before_action :show_splash_screen, only: :index
def landing def landing
authorize Video, :new? authorize Video, :new?
@@ -60,6 +61,10 @@ class VideosController < ApplicationController
private private
def show_splash_screen
render :splash if videos.count.zero?
end
def set_project def set_project
@project = policy_scope(Project).find(params[:project_id]) @project = policy_scope(Project).find(params[:project_id])
end end

View File

@@ -5,7 +5,7 @@ class ZoomNotificationsController < ApplicationController
skip_before_action :verify_authenticity_token skip_before_action :verify_authenticity_token
before_action :authorize_zoom before_action :authorize_zoom
before_action :set_zoom_meeting, only: :create before_action :set_zoom_meeting, only: [:create], if: :meeting_event?
def create def create
case notification_event case notification_event
@@ -16,6 +16,12 @@ class ZoomNotificationsController < ApplicationController
when 'recording.completed' when 'recording.completed'
recording = notification.dig(:payload, :object, :recording_files).first recording = notification.dig(:payload, :object, :recording_files).first
AttachRecordingToZoomMeetingJob.perform_later(@zoom_meeting, recording, notification['download_token']) AttachRecordingToZoomMeetingJob.perform_later(@zoom_meeting, recording, notification['download_token'])
when 'user.deleted'
zoom_user = ZoomUser.find_by(api_id: notification.dig(:payload, :object, :id))
if zoom_user.present?
zoom_user.api_id = nil
zoom_user.destroy
end
else else
Rails.logger.info notification_event Rails.logger.info notification_event
Rails.logger.info notification Rails.logger.info notification
@@ -42,6 +48,10 @@ class ZoomNotificationsController < ApplicationController
notification.dig(:payload, :object, :host_id) notification.dig(:payload, :object, :host_id)
end end
def meeting_event?
notification_event.split(".").first.to_s.in? %w(meeting recording)
end
def set_zoom_meeting def set_zoom_meeting
@zoom_meeting = ZoomMeeting.find_by!(api_meeting_id: notification_meeting_id) @zoom_meeting = ZoomMeeting.find_by!(api_meeting_id: notification_meeting_id)
end end

View File

@@ -7,8 +7,8 @@ module DescriptionListHelper
safe_join(tags) safe_join(tags)
end end
def description_list_pair_for(record, attribute, append: nil) def description_list_pair_for(record, attribute, append: nil, custom_label: nil)
term = translation_for(record, attribute) term = custom_label.nil? ? translation_for(record, attribute) : custom_label
definition = record.send(attribute) definition = record.send(attribute)
description_list_pair(term, definition, append: append) description_list_pair(term, definition, append: append)

View File

@@ -2,11 +2,17 @@ module DropzoneHelper
def dropzone_placeholder_message_for(releasable) def dropzone_placeholder_message_for(releasable)
case releasable.model_name.param_key case releasable.model_name.param_key
when "acquired_media_release" when "acquired_media_release"
"To Add Photos & Videos to the release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse photos and connect to Camera" '(Optional) To add the licensed photos or videos ("Property") to this release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse photos and connect to Camera'
when "material_release"
t 'material_releases.form.photos.dropzone_label'
when "music_release" when "music_release"
"To Add Audio Files to the release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse files" "To Add Audio Files to the release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse files"
when "location_release"
t 'location_releases.form.photos.dropzone_label'
when "directory" when "directory"
"To Add Files to the Folder:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse files" "To Add Files to the Folder:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse files"
when "task_request"
"To Add Files for the Task:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse files"
else else
"To Add Photos to the release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse photos and connect to Camera" "To Add Photos to the release:<br>Drag & Drop Files<br>or<br>Click or Tap here to browse photos and connect to Camera"
end end

View File

@@ -6,6 +6,6 @@ module MailHelper
"1. Tell us the name of the video: \n\n" \ "1. Tell us the name of the video: \n\n" \
"2. Attach each EDL to this email. Please make sure to indicate whether the EDL is a Video Only, Graphics Only, or Audio Only EDL." "2. Attach each EDL to this email. Please make sure to indicate whether the EDL is a Video Only, Graphics Only, or Audio Only EDL."
mail_to "info@bigmedia.ai", content, subject: subject, body: body mail_to "info@mesuite.ai", content, subject: subject, body: body
end end
end end

View File

@@ -5,4 +5,12 @@ module TooltipHelper
concat tag.div(class: "tooltip-inner") concat tag.div(class: "tooltip-inner")
end end
end end
def get_approval_data_for_releasable(release)
if release.approved_by_user_name.present?
"#{release.approved_by_user_name} [#{release.approved_by_user_email}]"
else
release.approved_by_user_email
end
end
end end

View File

@@ -13,10 +13,13 @@ module WordmarkHelper
css += options[:class].to_s css += options[:class].to_s
content_tag(:div, class: css) do content_tag(:div, class: css) do
safe_join [ elements = [
content_tag(:span, t("shared.#{product_name}")), content_tag(:span, t("shared.#{product_name}")),
content_tag(:span, t("shared.me")) content_tag(:span, t("shared.me"))
] ]
prefix = options[:prefix]
elements.unshift content_tag(:span, "#{prefix} ") unless prefix.blank?
safe_join elements
end end
end end
end end

View File

@@ -67,6 +67,23 @@ class ActiveStorageDropzone {
var upload = new that.UploaderClass(file, url, delegate); var upload = new that.UploaderClass(file, url, delegate);
createUpload(this, upload); createUpload(this, upload);
}); });
this.on("addedfile", function(file) {
// Show download link in dropzone previews
let div = document.createElement("div");
let anchor = document.createElement("a");
let download_icon = "<i class='fa fa-download' aria-hidden='true'></i> Download";
anchor.innerHTML = download_icon;
anchor.href = file.dataURL;
anchor.setAttribute('target', '_blank');
anchor.setAttribute('style', 'background-color: rgba(255, 255, 255, 0.4); padding: 0 0.4em; border: 1px solid transparent; text-decoration: none;');
div.append(anchor);
div.setAttribute('class', 'dz-download-link')
div.setAttribute('style', 'margin-top: 1em;')
$(file.previewElement.childNodes[3]).append(div);
});
}, },
}); });

View File

@@ -1,5 +1,6 @@
$(document).on("turbolinks:load", () => { $(document).on("turbolinks:load", () => {
$('.datepicker-control').datepicker({ $('.datepicker-control').datepicker({
format: "yyyy-mm-dd" format: "yyyy-mm-dd",
todayHighlight: true
}); });
}); });

View File

@@ -1,4 +1,3 @@
require 'zoom_gateway'
class AttachRecordingToZoomMeetingJob < ApplicationJob class AttachRecordingToZoomMeetingJob < ApplicationJob
queue_as :default queue_as :default

View File

@@ -6,8 +6,8 @@ class GenerateContractsZipJob < ApplicationJob
before_perform do |job| before_perform do |job|
@project = job.arguments.first @project = job.arguments.first
@download = job.arguments.second @download = job.arguments.second
release_type = job.arguments.third @release_type = job.arguments.third
@folder_name = "#{@project.name.parameterize}_#{get_release_name(release_type).gsub('_', '-')}" @folder_name = "#{@project.name.parameterize}_#{get_release_name(@release_type).gsub('_', '-')}"
@download.update!(name: @folder_name, status: :pending) @download.update!(name: @folder_name, status: :pending)
end end
@@ -20,9 +20,14 @@ class GenerateContractsZipJob < ApplicationJob
files.each do |attachment| files.each do |attachment|
zipfile.add(attachment, File.join("#{dir}/", attachment)) zipfile.add(attachment, File.join("#{dir}/", attachment))
end end
if @release_type.constantize.include?(CsvExportable)
csv_file = generate_csv releases
zipfile.get_output_stream("#{@folder_name}.csv") { |f| f.puts(csv_file) }
end
end end
@download.file.attach(io: File.open(zipfile_name), filename: @folder_name) @download.file.attach(io: File.open(zipfile_name), filename: "#{@folder_name}.zip")
end end
rescue StandardError => e rescue StandardError => e
Rails.logger.error("Failed to generate download for project (##{project.id}) with release type #{release_type}\n" + e.message) Rails.logger.error("Failed to generate download for project (##{project.id}) with release type #{release_type}\n" + e.message)
@@ -43,6 +48,19 @@ class GenerateContractsZipJob < ApplicationJob
private private
def generate_csv(releases)
release_class = @release_type.constantize
headers = release_class.csv_headers
CSV.generate(headers: true) do |csv|
csv << headers
releases.each do |release|
csv_row_data = release.to_csv_row
csv << csv_row_data
end
end
end
def get_release_name(release_type) def get_release_name(release_type)
release_type.constantize.model_name.plural release_type.constantize.model_name.plural
end end

View File

@@ -0,0 +1,100 @@
# frozen_string_literal: true
class MatchAppearanceReleasesJob < ApplicationJob
queue_as :default
def perform(project, attachments)
filtered_attachments_object = filter_attachments attachments
return if filtered_attachments_object[:keys].blank?
matching_request = MatchingRequest.create project: project, attachments: filtered_attachments_object[:signed_ids]
payload = { request_id: matching_request.id, bucket: aws_bucket_name, files: filtered_attachments_object[:keys]}
response = BrayniacAI::QrMatching.create! payload
matches = response.matches || []
key_signed_id_hash = Hash[filtered_attachments_object[:keys].zip(filtered_attachments_object[:signed_ids])]
handle_matches matches, project, key_signed_id_hash
matching_request.destroy
end
private
def handle_matches(matches, project, key_signed_id_hash)
matches.each do |match|
contract_key = Array.wrap(match.contracts).first
headshot_key = Array.wrap(match.headshots).first
identifier = match.identifier
contract = key_signed_id_hash[contract_key]
headshot = key_signed_id_hash[headshot_key]
next if contract.nil? && headshot.nil?
identified_release = identifier.blank? ? nil : AppearanceRelease.find_by(identifier: identifier)
if identified_release.nil?
create_release project, contract, headshot, identifier
else
update_release identified_release, contract, headshot
end
end
end
def create_release(project, contract, headshot, identifier)
random_contract_no = AppearanceRelease.random_contract_number.to_s
is_incomplete = contract.nil? || headshot.nil?
params = {
project: project,
person_first_name: appearance_first_name(is_incomplete),
person_last_name: random_contract_no
}
params[:person_photo] = headshot unless headshot.nil?
params[:contract] = contract unless contract.nil?
params[:identifier] = identifier unless blank?
return if AppearanceRelease.create(params)
logger.error "Failed to create AppearanceRelease with params : \r\n#{params}"
end
def update_release(release, contract, headshot)
release.contract = contract unless contract.nil?
release.person_photo = headshot unless headshot.nil?
release.save
end
def appearance_first_name(incomplete)
if incomplete
I18n.t('appearance_releases.shared.incomplete_match')
else
I18n.t('appearance_releases.shared.matched_import')
end
end
def aws_bucket_name
ENV.fetch 'AWS_BUCKET'
end
def filter_attachments(attachments)
filtered_attachments_keys = []
filtered_attachments_signed_ids = []
attachments.each do |attachment|
blob = ActiveStorage::Blob.find_signed attachment
next if blob.nil?
extension = blob.filename.extension
next unless blob.image? || extension == 'pdf'
filtered_attachments_keys << blob.key
filtered_attachments_signed_ids << attachment
end
{
keys: filtered_attachments_keys,
signed_ids: filtered_attachments_signed_ids
}
end
end

View File

@@ -1,12 +1,14 @@
class SubmitHubspotFormJob < ApplicationJob class SubmitHubspotFormJob < ApplicationJob
queue_as :default queue_as :default
def perform(email, company_name, additional_params = {}) def perform(first_name, last_name, email, company_name, additional_params = {})
hubspot_form_guid = ENV["HUBSPOT_FORM_GUID"] hubspot_form_guid = ENV["HUBSPOT_FORM_GUID"]
return unless hubspot_form_guid.present? return unless hubspot_form_guid.present?
submission_params = { submission_params = {
email: email, first_name: first_name,
last_name: last_name,
email: email,
company: company_name company: company_name
}.merge(additional_params) }.merge(additional_params)

View File

@@ -0,0 +1,18 @@
class SubmitHubspotTaskRequestFormJob < ApplicationJob
queue_as :default
def perform(user_email, taskme_url)
hubspot_task_request_form_guid = ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"]
return unless hubspot_task_request_form_guid.present?
submission_params = {
email: user_email,
taskme_url: taskme_url
}
form = Hubspot::Form.new("guid" => hubspot_task_request_form_guid)
is_form_sumitted = form.submit(submission_params)
raise StandardError.new "Failed to submit the task request hubspot form data: #{is_form_sumitted}" unless is_form_sumitted
end
end

View File

@@ -1,5 +1,5 @@
class AdminMailer < ApplicationMailer class AdminMailer < ApplicationMailer
default to: %w(bray@bigmedia.ai lee@bigmedia.ai) default to: %w[bray@mesuite.ai]
def new_video(video) def new_video(video)
@video = video @video = video

View File

@@ -1,4 +1,4 @@
class ApplicationMailer < ActionMailer::Base class ApplicationMailer < ActionMailer::Base
default from: ENV.fetch("MAILER_FROM_ADDRESS") { "support@bigmedia.ai" } default from: ENV.fetch("MAILER_FROM_ADDRESS") { "support@mesuite.ai" }
layout "mailer" layout "mailer"
end end

View File

@@ -5,6 +5,7 @@ class Account < ApplicationRecord
has_many :users, through: :account_auths has_many :users, through: :account_auths
has_many :projects, dependent: :destroy has_many :projects, dependent: :destroy
has_many :videos, through: :projects has_many :videos, through: :projects
has_many :broadcasts, through: :projects
has_many :contract_templates, through: :projects has_many :contract_templates, through: :projects
validates :name, presence: true validates :name, presence: true
@@ -54,11 +55,28 @@ class Account < ApplicationRecord
Download.where(project: projects), Download.where(project: projects),
User.joins(:project_memberships).where(project_memberships: { project: projects }), User.joins(:project_memberships).where(project_memberships: { project: projects }),
Broadcast.where(project: projects), Broadcast.where(project: projects),
TaskRequest.where(project: projects),
ZoomMeeting.where(project: projects), ZoomMeeting.where(project: projects),
MedicalRelease.where(project: projects),
MiscRelease.where(project: projects),
MatchingRequest.where(project: projects),
self self
])).sum(:byte_size).to_f ])).sum(:byte_size).to_f
end end
def total_number_of_releases
[
MiscRelease.where(project: projects).size,
AppearanceRelease.where(project: projects).size,
TalentRelease.where(project: projects).size,
MaterialRelease.where(project: projects).size,
MedicalRelease.where(project: projects).size,
LocationRelease.where(project: projects).size,
AcquiredMediaRelease.where(project: projects).size,
MusicRelease.where(project: projects).size
].sum
end
def to_param def to_param
slug slug
end end
@@ -79,6 +97,10 @@ class Account < ApplicationRecord
plan_uid.to_s == "me_suite" || plan_uid.to_s == "releaseme" plan_uid.to_s == "me_suite" || plan_uid.to_s == "releaseme"
end end
def taskme_enabled?
plan_uid.to_s == "me_suite" || plan_uid.to_s == "taskme"
end
def plan_name def plan_name
case plan_uid.to_s case plan_uid.to_s
when "deliverme" when "deliverme"
@@ -87,6 +109,8 @@ class Account < ApplicationRecord
"DirectME" "DirectME"
when "releaseme" when "releaseme"
"ReleaseME" "ReleaseME"
when "taskme"
"TaskME"
when "me_suite" when "me_suite"
"ME Suite" "ME Suite"
end end

View File

@@ -9,10 +9,23 @@ class AcquiredMediaRelease < ApplicationRecord
include Signable include Signable
include Syncable include Syncable
include PersonName include PersonName
include CsvExportable
include Approvable
include GuardianPhotoable
include SecondGuardianPhotoable
include GuardianName
include SecondGuardianName
class << self
def custom_csv_exportable_headers
%i[name files_count owner_info]
end
end
# This association needs to be removed after changing the API. Removing it right now will cause failure in API specs.
has_many :file_infos, as: :releasable, dependent: :destroy has_many :file_infos, as: :releasable, dependent: :destroy
accepts_nested_attributes_for :file_infos has_many_attached :files
composed_of :person_address, composed_of :person_address,
class_name: "Address", class_name: "Address",
@@ -25,6 +38,38 @@ class AcquiredMediaRelease < ApplicationRecord
%w(person_address_country country) %w(person_address_country country)
] ]
composed_of :guardian_address,
class_name: 'Address',
mapping: [
%w[guardian_address_street1 street1],
%w[guardian_address_street2 street2],
%w[guardian_address_city city],
%w[guardian_address_state state],
%w[guardian_address_zip zip],
%w[guardian_address_country country]
]
composed_of :guardian_2_address,
class_name: 'Address',
mapping: [
%w[guardian_2_address_street1 street1],
%w[guardian_2_address_street2 street2],
%w[guardian_2_address_city city],
%w[guardian_2_address_state state],
%w[guardian_2_address_zip zip],
%w[guardian_2_address_country country]
]
# We don't care for the argument but method WILL receive option name
# when called from inside with_option block, hence * argument
def self.face_photo_acceptable_content_types(*)
['image/png', 'image/jpeg']
end
def self.acceptable_import_file_extensions
['.png', '.jpeg', '.jpg', '.pdf']
end
validates :name, presence: true validates :name, presence: true
validates :person_email, email: true, allow_blank: true validates :person_email, email: true, allow_blank: true
@@ -43,10 +88,11 @@ class AcquiredMediaRelease < ApplicationRecord
person_address_street1 person_address_street2 person_address_city person_address_state person_address_zip person_address_country person_address_street1 person_address_street2 person_address_city person_address_state person_address_zip person_address_country
] ]
CATEGORIES = ["Artwork", "Film Footage", "Video Footage", "Still Photograph"].freeze # CATEGORIES = ["Artwork", "Film Footage", "Video Footage", "Still Photograph"].freeze
CATEGORIES = ["Film Footage", "Video Footage", "Still Photograph"].freeze
def minor? def second_guardian_present?
false guardian_2_first_name.present?
end end
def contact_person def contact_person
@@ -56,4 +102,20 @@ class AcquiredMediaRelease < ApplicationRecord
def uses_edl? def uses_edl?
true true
end end
def files_count
files.any? ? files.size : I18n.t('acquired_media_releases.acquired_media_release.no_media')
end
def image_files
files_blobs.where("content_type ILIKE ?", "%image%")
end
def video_files
files_blobs.where("content_type ILIKE ?", "%video%")
end
def other_files
files_blobs.where("NOT content_type ILIKE ANY (array[?])", ["%image%", "%video%"])
end
end end

View File

@@ -40,7 +40,7 @@ class AppHost
use_ssl: false, use_ssl: false,
}, },
production: { production: {
host: "bigmedia.ai", host: "mesuite.ai",
use_ssl: true, use_ssl: true,
} }
} }

View File

@@ -12,10 +12,57 @@ class AppearanceRelease < ApplicationRecord
include Taggable include Taggable
include PersonName include PersonName
include GuardianPhotoable include GuardianPhotoable
include SecondGuardianPhotoable
include GuardianName include GuardianName
include SecondGuardianName
include CsvExportable
include Approvable
include Amendmenable
NUMBER_OF_CUSTOM_FIELDS = 15
class << self
def custom_csv_exportable_headers
%i[name contact_info]
end
end
has_one_attached :person_photo has_one_attached :person_photo
composed_of :person_address,
class_name: 'Address',
mapping: [
%w[person_address_street1 street1],
%w[person_address_street2 street2],
%w[person_address_city city],
%w[person_address_state state],
%w[person_address_zip zip],
%w[person_address_country country]
]
composed_of :guardian_address,
class_name: 'Address',
mapping: [
%w[guardian_address_street1 street1],
%w[guardian_address_street2 street2],
%w[guardian_address_city city],
%w[guardian_address_state state],
%w[guardian_address_zip zip],
%w[guardian_address_country country]
]
composed_of :guardian_2_address,
class_name: 'Address',
mapping: [
%w[guardian_2_address_street1 street1],
%w[guardian_2_address_street2 street2],
%w[guardian_2_address_city city],
%w[guardian_2_address_state state],
%w[guardian_2_address_zip zip],
%w[guardian_2_address_country country]
]
# These validations apply to all releases # These validations apply to all releases
validates :person_email, email: true, allow_blank: true validates :person_email, email: true, allow_blank: true
validates :person_first_name, :person_last_name, presence: true validates :person_first_name, :person_last_name, presence: true
@@ -39,6 +86,7 @@ class AppearanceRelease < ApplicationRecord
# These validations apply to releases being signed by a minor # These validations apply to releases being signed by a minor
with_options if: :minor? do with_options if: :minor? do
validates :guardian_first_name, :guardian_last_name, presence: true validates :guardian_first_name, :guardian_last_name, presence: true
validates :guardian_email, email: true, allow_blank: true
end end
validates :person_photo, content_type: face_photo_acceptable_content_types validates :person_photo, content_type: face_photo_acceptable_content_types
@@ -70,7 +118,18 @@ class AppearanceRelease < ApplicationRecord
scope :having_no_person_photo, -> { left_joins(:person_photo_attachment).group(:id).having('COUNT(active_storage_attachments) = 0') } scope :having_no_person_photo, -> { left_joins(:person_photo_attachment).group(:id).having('COUNT(active_storage_attachments) = 0') }
scope :with_person_name, ->(name) { where('person_first_name ILIKE ? OR person_last_name ILIKE ?', "%#{name}%") } scope :with_person_name, ->(name) { where('person_first_name ILIKE ? OR person_last_name ILIKE ?', "%#{name}%") }
searchable_on %i[person_first_name person_last_name person_address person_email person_phone] searchable_on %i[
person_first_name
person_last_name
person_address_street1
person_address_street2
person_address_city
person_address_state
person_address_zip
person_address_country
person_email
person_phone
]
# All releases must respond to the following messages # All releases must respond to the following messages
def name def name
@@ -97,6 +156,10 @@ class AppearanceRelease < ApplicationRecord
true true
end end
def second_guardian_present?
self.guardian_2_first_name.present?
end
def contract_file_name def contract_file_name
"#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime('%Y.%m.%d')}_#{release_number}_#{filename_suffix.parameterize}" "#{project.name.parameterize}_#{contract_template.release_type}_#{(signed_at || created_at).strftime('%Y.%m.%d')}_#{release_number}_#{filename_suffix.parameterize}"
end end

View File

@@ -8,7 +8,7 @@ class BlankContract
end end
def to_pdf def to_pdf
kit = PDFKit.new(as_html) kit = PDFKit.new(as_html, margin_right: 1, margin_left: 1, margin_top: 10, margin_bottom: 1)
kit.to_file("tmp/#{filename}") kit.to_file("tmp/#{filename}")
end end

View File

@@ -30,8 +30,16 @@ class Broadcast < ApplicationRecord
"https://stream.mux.com/#{stream_playback_uid}.m3u8" "https://stream.mux.com/#{stream_playback_uid}.m3u8"
end end
def full_live_stream_playback_url
full_live_stream_playback_uid.blank? ? stream_playback_url : "https://stream.mux.com/#{full_live_stream_playback_uid}.m3u8"
end
def stream_server_url def stream_server_url
ENV['MUX_BROADCAST_SERVER_URL'] stream_url_override.presence || ENV["MUX_BROADCAST_SERVER_URL"]
end
def stream_server_key
stream_key_override.presence || stream_key
end end
def zoom_meeting_url def zoom_meeting_url
@@ -41,11 +49,13 @@ class Broadcast < ApplicationRecord
private private
def create_mux_live_stream def create_mux_live_stream
stream = MuxLiveStream.new stream = MuxLiveStream.create_with_simulcast
self.stream_uid = stream.id self.stream_uid = stream.id
self.stream_key = stream.key self.stream_key = stream.key
self.stream_playback_uid = stream.playback_id self.stream_playback_uid = stream.playback_id
self.simulcast_uid = stream.simulcast_id
self.director_mode_video_embed ||= stream.simulcast_destination.try(:playback_embed)
self.save! self.save!
end end

View File

@@ -5,6 +5,8 @@ class BroadcastRecording < ApplicationRecord
validates :asset_uid, uniqueness: true validates :asset_uid, uniqueness: true
scope :visible, -> { where(hidden: false) }
def download_url def download_url
"https://stream.mux.com/#{asset_playback_uid}/#{file_name}?download=#{download_file_name}" "https://stream.mux.com/#{asset_playback_uid}/#{file_name}?download=#{download_file_name}"
end end
@@ -14,6 +16,6 @@ class BroadcastRecording < ApplicationRecord
end end
def download_file_name def download_file_name
"#{broadcast_name}_Date_#{created_at.strftime("%Y-%m-%d")}_Time_#{created_at.strftime("%T")}".parameterize "#{broadcast_name}_Date_#{created_at.in_time_zone(broadcast.shoot_location_time_zone).strftime("%Y-%m-%d")}_Time_#{created_at.in_time_zone(broadcast.shoot_location_time_zone).strftime("%T")}".parameterize
end end
end end

View File

@@ -0,0 +1,32 @@
module Amendmenable
extend ActiveSupport::Concern
included do
include ActiveStorageSupport::SupportForBase64
has_one_base64_attached :amendment_signature
with_options on: :amendment do
validates :amendment_signer_name, presence: true
validates :amendment_signature, attached: true
end
end
def amendment_signable?
contract_template.present? && contract_template.amendment_clause.present?
end
def amendment_signed?
amendment_signature.attached?
end
def amendment_signature_base64
nil
end
def amendment_signature_base64=(data_uri)
return if data_uri.blank?
amendment_signature.attach(data: data_uri, filename: "amendment_signature.png", content_type: "image/png", identify: "false")
end
end

View File

@@ -0,0 +1,26 @@
module Approvable
extend ActiveSupport::Concern
included do
include ActiveStorageSupport::SupportForBase64
has_one_base64_attached :approved_by_user_signature
# Requires signature when saving in the approval context
with_options on: :approval do
validates :approved_by_user_signature, attached: true
end
def approve_by(user)
return unless approved_at.nil?
self.approved_by_user_name = user.full_name
self.approved_by_user_email = user.email
self.approved_at = BigMediaTime.time_zone_now
end
def approved?
self.approved_at.present?
end
end
end

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
module Attachable
extend ActiveSupport::Concern
included do
has_many_attached :attachments
end
end

View File

@@ -0,0 +1,65 @@
# frozen_string_literal: true
module CsvExportable
extend ActiveSupport::Concern
COMMON_HEADERS = %i[approved notes tags signed_at].freeze
COMMON_VALUES = %w[approved? clean_notes clean_tags signed_on].freeze
included do
class << self
def custom_csv_exportable_headers
[]
end
def csv_headers
headers = custom_csv_exportable_headers + COMMON_HEADERS
headers.map do |header|
I18n.t("#{model_name.plural}.index.table_headers.#{header}")
end
end
end
def to_csv_row
(self.class.custom_csv_exportable_headers + COMMON_VALUES).map do |function|
send(function)
end
end
private
def owner_info
compact_contact_info(name: person_name, address: person_address, phone: person_phone, email: person_email)
end
def contact_info
owner_info
end
def compact_contact_info(name: nil, address: nil, phone: nil, email: nil)
contact_info = ''
contact_info += "#{name}; " if name.present?
contact_info += "#{address}; " if address.present?
contact_info += "P: #{phone}; " if phone.present?
contact_info += "E: #{email}" if email.present?
contact_info.delete_suffix '; '
end
def clean_notes
notes = ''
self.notes.order_by_recent.each do |note|
notes += "#{note.content}(#{note.email}), "
end
notes.delete_suffix ', '
end
def clean_tags
tags = ''
self.tags.each do |tag|
tags += "#{tag.name}, "
end
tags.delete_suffix ', '
end
end
end

View File

@@ -0,0 +1,20 @@
module SecondGuardianName
extend ActiveSupport::Concern
included do
def guardian_2_name
"#{guardian_2_first_name} #{guardian_2_last_name}".titleize
end
def guardian_2_name=(value)
if value.include?(' ')
split = value.split(" ", 2)
self.guardian_2_first_name = split.first
self.guardian_2_last_name = split.last
else
self.guardian_2_first_name = value
self.guardian_2_last_name = "(Not Given)"
end
end
end
end

View File

@@ -0,0 +1,9 @@
module SecondGuardianPhotoable
extend ActiveSupport::Concern
included do
has_one_attached :guardian_2_photo
validates :guardian_2_photo, content_type: ["image/png", "image/jpeg"]
end
end

View File

@@ -29,6 +29,10 @@ class Contract
} }
end end
def medical_release?
@releasable.instance_of?(MedicalRelease)
end
private private
def contract_template def contract_template

View File

@@ -5,6 +5,8 @@ class ContractTemplate < ApplicationRecord
include Syncable include Syncable
include PgSearch include PgSearch
NUMBER_OF_CUSTOM_FIELDS = 15
belongs_to :project belongs_to :project
belongs_to :parent, class_name: 'ContractTemplate', optional: true belongs_to :parent, class_name: 'ContractTemplate', optional: true
has_many :duplicates, class_name: 'ContractTemplate', foreign_key: 'parent_id' has_many :duplicates, class_name: 'ContractTemplate', foreign_key: 'parent_id'
@@ -13,10 +15,17 @@ class ContractTemplate < ApplicationRecord
has_many :acquired_media_releases, dependent: :restrict_with_error has_many :acquired_media_releases, dependent: :restrict_with_error
has_many :location_releases, dependent: :restrict_with_error has_many :location_releases, dependent: :restrict_with_error
has_many :material_releases, dependent: :restrict_with_error has_many :material_releases, dependent: :restrict_with_error
has_many :medical_releases, dependent: :restrict_with_error
has_many :misc_releases, dependent: :restrict_with_error
monetize :fee_cents monetize :fee_cents
has_rich_text :body has_rich_text :body
has_rich_text :guardian_clause has_rich_text :guardian_clause
has_rich_text :signature_legal_text
has_rich_text :amendment_clause
has_rich_text :exhibit_a_legal_text
has_rich_text :exhibit_b_legal_text
has_rich_text :questionnaire_legal_text
validates :name, presence: true validates :name, presence: true
validates :release_type, presence: true validates :release_type, presence: true
@@ -38,6 +47,8 @@ class ContractTemplate < ApplicationRecord
scope :non_archived, -> { where(archived_at: nil) } scope :non_archived, -> { where(archived_at: nil) }
scope :order_by_name, -> { order(:name) } scope :order_by_name, -> { order(:name) }
enum accessibility: [:public_template, :private_template]
def fee? def fee?
!fee.zero? !fee.zero?
end end
@@ -50,7 +61,33 @@ class ContractTemplate < ApplicationRecord
parent.present? parent.present?
end end
def archived?
archived_at.present?
end
def archive def archive
update(archived_at: Time.zone.now) update(archived_at: Time.zone.now)
end end
def has_questionnaire?
(1..NUMBER_OF_CUSTOM_FIELDS).any? { |n| public_send("question_#{n}_text").presence }
end
def has_exhibit_a?
exhibit_a_legal_text.present?
end
def has_exhibit_b?
exhibit_b_legal_text.present?
end
def editable?
releases.size.zero?
end
def attributes
result = super()
result[:signature_legal_text] = signature_legal_text.as_json
result
end
end end

View File

@@ -23,7 +23,7 @@ class HeadshotCollection
collection_uid: collection_uid.to_s, collection_uid: collection_uid.to_s,
bucket_name: aws_bucket_name, bucket_name: aws_bucket_name,
ids_to_images: map_ids_to_images, ids_to_images: map_ids_to_images,
}.reject { |_, v| v.blank? } }.reject { |k, v| v.blank? && k != :ids_to_images }
end end
private private

View File

@@ -10,6 +10,15 @@ class LocationRelease < ApplicationRecord
include Syncable include Syncable
include Taggable include Taggable
include PersonName include PersonName
include CsvExportable
include Approvable
include Amendmenable
class << self
def custom_csv_exportable_headers
%i[location_info owner_info amendment_signed_column]
end
end
composed_of :address, composed_of :address,
mapping: [ mapping: [
@@ -58,6 +67,18 @@ class LocationRelease < ApplicationRecord
true true
end end
def location_info
compact_contact_info(name: name, address: address)
end
def amendment_signed_column
if amendment_signable?
amendment_signed?
else
I18n.t('location_releases.csv.no_amendment_clause')
end
end
private private
def end_date_after_start_date def end_date_after_start_date

Some files were not shown because too many files have changed in this diff Show More