Initial commit

This commit is contained in:
Senad Uka
2020-05-31 22:38:19 +02:00
commit 858fafc3c5
1280 changed files with 65918 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,48 @@
class Api::ApiController < ActionController::Base
skip_before_action :verify_authenticity_token
include Knock::Authenticable
include Pundit
rescue_from Exception, :with => :return_error
before_action :authenticate_user
before_action do
Current.user = current_user if current_user.present?
end
def pundit_user
UserContext.new(Current.user, Current.account)
end
# Catch exception and return JSON-formatted error
def return_error(exception)
raise exception if Rails.env.test?
logger.error "==Handled======="
logger.error exception.message
logger.error exception.backtrace.join("\n")
logger.error "==Handled======="
case exception.class
when ActiveRecord::RecordNotFound
@status = 404
@message = 'Record not found'
when ActiveRecord::RecordInvalid
@status = 422
@message = 'Record invalid'
when ArgumentError
@status = 400
@message = 'Argument Error'
else
@status = 500
@message = 'Internal Error'
end
# for some reason render json_errors is not working
# simulating JSON API support
render json: {
errors: [{
status: @status.to_s,
title: @message
}]
}
end
end

View File

@@ -0,0 +1,23 @@
class Api::AppearanceReleasesController < Api::ReleasesController
deserializable_resource :appearance_release, only: [:create]
def model_name
"appearance_release"
end
def attributes_for_index
[:person_name]
end
def handle_attachments(release, _)
photo = release_create_params[:person_photo]
photo[:io] = StringIO.new(Base64.decode64(photo[:io]))
release.person_photo.attach(io: photo[:io], filename: photo[:filename])
guardian_photo = release_create_params[:guardian_photo]
if guardian_photo
guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io]))
release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename])
end
end
end

View File

@@ -0,0 +1,55 @@
# frozen_string_literal: true
class Api::BroadcastsController < Api::ApiController
deserializable_resource :broadcast, only: [:update]
include ProjectContext
before_action :set_project
before_action :set_broadcast, only: [:show, :update]
def index
render jsonapi: broadcasts, class: { Broadcast: SerializableBroadcast }
end
def show
render jsonapi:
@broadcast,
class: {
Broadcast: SerializableBroadcast,
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment
},
include: [:files]
end
def update
file_params.each do |file|
file[:io] = StringIO.new(Base64.decode64(file[:io]))
@broadcast.files.attach(io: file[:io], filename: file[:filename])
end
@broadcast.save!
render jsonapi:
@broadcast,
class: {
Broadcast: SerializableBroadcast,
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment
},
include: [:files]
end
private
def file_params
broadcast_params = params.require(:broadcast).permit!
broadcast_params[:files]
end
def broadcasts
policy_scope(@project.broadcasts.where(status: %w[created idle]))
end
def set_broadcast
@broadcast = authorize policy_scope(@project.broadcasts).find(params[:id])
end
end

View File

@@ -0,0 +1,63 @@
class Api::ContractTemplatesController < Api::ApiController
include ProjectContext
before_action :set_project, only: [:index]
before_action :set_contract_template, only: [:show]
def index
render jsonapi: contract_templates, class: { "ContractTemplate": index_serializable }
end
def show
handle_response(@contract_template)
end
def handle_response(contract_template, status = :ok)
mapping = {
"ContractTemplate": show_serializable,
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment,
}
render jsonapi: contract_template,
status: status,
class: mapping
end
def attributes_for_index
[:name]
end
def index_serializable
name = "contract_template"
attributes_to_send = attributes_for_index
Class.new(JSONAPI::Serializable::Resource) do
type name
attributes_to_send.each do |attr|
attribute attr.to_sym
end
end
end
def show_serializable
name = "contract_template"
Class.new(JSONAPI::Serializable::Resource) do
type name
ContractTemplate.new.attributes.keys.each do |attr|
attribute attr.to_sym
end
end
end
private
def contract_templates
date = Date.parse(params.fetch(:updated_since, Date.new.to_s))
policy_scope(ContractTemplate.where(project_id: @project.id, updated_at: date..Float::INFINITY))
end
def set_contract_template
@contract_template = ContractTemplate.find(params[:id])
end
end

View File

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

View File

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

View File

@@ -0,0 +1,35 @@
class Api::NotesController < Api::ApiController
before_action :set_release
deserializable_resource :note, only: [:create]
def index
render jsonapi: @release.notes, class: { Note: SerializableNote }
end
def create
note = @release.notes.new(note_create_params)
note.user_id = current_user.id
note.email = current_user.email
note.save!
render jsonapi: note, class: { Note: SerializableNote }, status: :created
end
private
def model_name
request.path.match(/(\w+_releases)/).captures.first.singularize
end
def model_constant
model_name.camelize.constantize
end
def set_release
@release = authorize model_constant.find(params["#{model_name}_id"])
end
def note_create_params
parameters = params.require(:note).permit!
parameters.slice(:content)
end
end

View File

@@ -0,0 +1,5 @@
class Api::ProfilesController < Api::ApiController
def show
render jsonapi: current_user
end
end

View File

@@ -0,0 +1,6 @@
class Api::ProjectsController < Api::ApiController
def index
projects = Current.user.accessible_projects_for(Current.account)
render jsonapi: projects
end
end

View File

@@ -0,0 +1,182 @@
class Api::ReleasesController < Api::ApiController
include ProjectContext
include CreateReleasableJobs
before_action :set_project, only: [:index]
before_action :set_release, only: [:show, :update]
before_action :set_template_and_project, only: [:create]
def index
render jsonapi: releases, class: { "#{model_name.camelize}": index_serializable }
end
def show
handle_response(@release)
end
def create
params_without_photo = release_create_params.except(:photos, :person_photo)
release = filtered_releases.new(params_without_photo)
release.project_id = @project.id
release.contract_template_id = @contract_template.id
handle_attachments(release, release_create_params[:photos])
release.save!(context: :native)
log_create_analytics
after_create(release)
handle_response(release, :created)
end
def update
if model_name == "acquired_media_release"
authorize @release, :update_file_infos?
@release.attributes = release_create_params
@release.save!
else
authorize @release, :update_photos?
handle_attachments(@release, release_create_params[:photos])
@release.save!
end
handle_response(@release)
end
def handle_response(release, status = :ok)
if model_name == "acquired_media_release"
mapping = {
"#{model_name.camelize}": SerializableAcquiredMediaRelease,
FileInfo: SerializableFileInfo
}
render jsonapi: release,
status: status,
class: mapping,
include: [:file_infos]
else
mapping = {
"#{model_name.camelize}": show_serializable,
"ActiveStorage::Attachment".to_sym => ActiveStorage::SerializableAttachment,
}
render jsonapi: release,
status: status,
class: mapping,
include: [:photos, :guardian_photos]
end
end
def model_name
raise "Please specify model name underscored and lowercase e.g. appearance_release"
end
def model_constant
model_name.camelize.constantize
end
def attributes_for_index
raise "Please specify attributes for index"
end
def index_serializable
name = model_name
attributes_to_send = attributes_for_index
Class.new(JSONAPI::Serializable::Resource) do
type name
attributes_to_send.each do |attr|
attribute attr.to_sym
end
end
end
def show_serializable
name = model_name
constant = model_constant
Class.new(JSONAPI::Serializable::Resource) do
type name
constant.new.attributes.keys.each do |attr|
attribute attr.to_sym
end
if ["appearance_release", "talent_release"].include?(name)
has_many :guardian_photos do
data do
[@object.guardian_photo.try(:attachment)].compact
end
meta do
{ count: @object.try(:guardian_photo).try(:attached?) ? 1 : 0 }
end
end
end
unless name == "acquired_media_release"
has_many :photos do
if name == "appearance_release"
data do
[@object.photo.attachment]
end
end
meta do
{ count: @object.photos.size }
end
end
end
end
end
def create_deserializable
constant = model_constant
Class.new(JSONAPI::Deserializable::Resource) do
constant.new.attributes.keys.except(:created_at, :updated_at, :id, :user_id).each do |attr|
attribute attr.to_sym
end
end
end
def handle_attachments(release, params_photos)
photos = params_photos || []
photos.each do |photo|
photo[:io] = StringIO.new(Base64.decode64(photo[:io]))
release.photos.attach(io: photo[:io], filename: photo[:filename])
end
end
private
def releases
date = Date.parse(params.fetch(:updated_since, Date.new.to_s))
table = model_constant.table_name
policy_scope(model_constant.where(["#{table}.project_id = ? and #{table}.updated_at >= ?", @project.id, date]))
end
def set_release
@release = model_constant.find(params[:id])
end
def set_template_and_project
@contract_template = ContractTemplate.find(params[:contract_template_id])
@project = @contract_template.project
end
def filtered_releases
if @project.present?
policy_scope(@project.public_send(model_name.pluralize))
else
releases
end
end
def release_create_params
parameters = params.require(model_name).permit!
keys = model_constant.new.attributes.keys + [:guardian_photo, :person_photo, :photos, :signature, :signature_base64, :file_infos_attributes]
parameters[:signature_base64] = parameters[:signature]
parameters = parameters.slice(*keys).except(:created_at, :updated_at, :id, :user_id, :signature)
parameters
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

View File

@@ -0,0 +1,78 @@
# frozen_string_literal: true
class Api::SyncController < Api::ApiController
def index
accessible_projects = current_user.accessible_projects_for(Current.account)
@accounts = filter(current_user.accounts)
@projects = filter(Project).all
@contract_templates = filter(ContractTemplate.where(project: accessible_projects)).all
@acquired_media_releases = (AcquiredMediaRelease.where(project: accessible_projects))
@appearance_releases = (AppearanceRelease.where(project: accessible_projects))
@location_releases = (LocationRelease.where(project: accessible_projects))
@material_releases = (MaterialRelease.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 ))
render json: {
data: {
accounts: @accounts,
projects: @projects,
contract_templates: @contract_templates,
acquired_media_releases: releases_query(@acquired_media_releases),
appearance_releases: releases_query(@appearance_releases),
location_releases: releases_query(@location_releases),
material_releases: releases_query(@material_releases),
talent_releases: releases_query(@talent_releases),
notes: @notes
}
}
end
private
def releases_query(release)
filter(release).all.map { |release| release_json(release) }
end
def notes_query(notes)
filter(notes).all.map do |note|
json = note.as_json
json[:attributes][:email] = note.email
json
end
end
def release_json(release)
json = release.as_json
unless release.model_name.to_s == "AcquiredMediaRelease"
json[:attributes][:photos] = release.photos.map do |photo|
build_photo_object photo
end
end
if release.respond_to?(:guardian_photo)
photo = release.guardian_photo
json[:attributes][:guardian_photo] = photo.attached? ? build_photo_object(photo) : nil
end
json
end
def filter(relation)
policy_scope(relation)
end
def build_photo_object(photo)
{
id: photo.id.to_s,
type: 'active_storage_attachment',
attributes: {
filename: photo.filename.to_s,
content_type: photo.content_type,
url: Rails.application.routes.url_helpers.rails_blob_url(photo, host: AppHost.new.domain_with_port),
thumbnail_url: Rails.application.routes.url_helpers.rails_representation_url(photo.variant(resize: '150x150'), host: AppHost.new.domain_with_port)
}
}
end
end

View File

@@ -0,0 +1,21 @@
class Api::TalentReleasesController < Api::ReleasesController
deserializable_resource :talent_release, only: [:create, :update]
def model_name
"talent_release"
end
def attributes_for_index
[:person_name]
end
def handle_attachments(release, _)
super
guardian_photo = release_create_params[:guardian_photo]
if guardian_photo
guardian_photo[:io] = StringIO.new(Base64.decode64(guardian_photo[:io]))
release.guardian_photo.attach(io: guardian_photo[:io], filename: guardian_photo[:filename])
end
end
end

View File

@@ -0,0 +1,36 @@
class Api::UserTokenController < Knock::AuthTokenController
skip_before_action :verify_authenticity_token
rescue_from Exception, :with => :return_error
# Catch exception and return JSON-formatted error
def return_error(exception)
logger.error "==Handled======="
logger.error exception.message
logger.error exception.backtrace.join("\n")
logger.error "==Handled======="
case exception
when ActiveRecord::RecordNotFound
@status = 404
@message = 'Record not found'
when ActiveRecord::RecordInvalid
@status = 422
@message = 'Record invalid'
when ArgumentError
@status = 400
@message = 'Argument Error'
else
@status = 500
@message = 'Internal Error'
end
# for some reason render json_errors is not working
# simulating JSON API support
render json: {
errors: [{
status: @status.to_s,
title: @message
}]
}
end
end